Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRebecca Turner <me@re-becca.org>2015-05-22 11:33:46 +0300
committerRebecca Turner <me@re-becca.org>2015-06-26 03:27:03 +0300
commitd3c858ce4cfb3aee515bb299eb034fe1b5e44344 (patch)
treee7714c839934a729b68038f4c7dc5ec3ed877638 /node_modules/gauge
parent24564b9654528d23c726cf9ea82b1aef2044b692 (diff)
deps: deduplicate npm@3 style
Diffstat (limited to 'node_modules/gauge')
-rw-r--r--node_modules/gauge/.npmignore32
-rw-r--r--node_modules/gauge/LICENSE13
-rw-r--r--node_modules/gauge/README.md161
-rw-r--r--node_modules/gauge/example.pngbin0 -> 19689 bytes
-rw-r--r--node_modules/gauge/package.json83
-rw-r--r--node_modules/gauge/progress-bar.js209
-rw-r--r--node_modules/gauge/test/progress-bar.js148
7 files changed, 646 insertions, 0 deletions
diff --git a/node_modules/gauge/.npmignore b/node_modules/gauge/.npmignore
new file mode 100644
index 000000000..df22a16c6
--- /dev/null
+++ b/node_modules/gauge/.npmignore
@@ -0,0 +1,32 @@
+# Logs
+logs
+*.log
+
+# Runtime data
+pids
+*.pid
+*.seed
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Compiled binary addons (http://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directory
+# Commenting this out is preferred by some people, see
+# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
+node_modules
+
+# Users Environment Variables
+.lock-wscript
+
+# Editor cruft
+*~
+.#*
diff --git a/node_modules/gauge/LICENSE b/node_modules/gauge/LICENSE
new file mode 100644
index 000000000..e75605296
--- /dev/null
+++ b/node_modules/gauge/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2014, Rebecca Turner <me@re-becca.org>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/node_modules/gauge/README.md b/node_modules/gauge/README.md
new file mode 100644
index 000000000..fb9eb0a7d
--- /dev/null
+++ b/node_modules/gauge/README.md
@@ -0,0 +1,161 @@
+gauge
+=====
+
+A nearly stateless terminal based horizontal guage / progress bar.
+
+```javascript
+var Gauge = require("gauge")
+
+var gauge = new Gauge()
+
+gauge.show("test", 0.20)
+
+gauge.pulse("this")
+
+gauge.hide()
+```
+
+![](example.png)
+
+
+### `var gauge = new Gauge([options], [ansiStream])`
+
+* **options** – *(optional)* An option object. (See [below] for details.)
+* **ansiStream** – *(optional)* A stream that's been blessed by the [ansi]
+ module to include various commands for controlling the cursor in a terminal.
+
+[ansi]: https://www.npmjs.com/package/ansi
+[below]: #theme-objects
+
+Constructs a new gauge. Gauges are drawn on a single line, and are not drawn
+if the current terminal isn't a tty.
+
+The **options** object can have the following properties, all of which are
+optional:
+
+* maxUpdateFrequency: defaults to 50 msec, the gauge will not be drawn more
+ than once in this period of time. This applies to `show` and `pulse`
+ calls, but if you `hide` and then `show` the gauge it will draw it
+ regardless of time since last draw.
+* theme: defaults to Gauge.unicode` if the terminal supports
+ unicode according to [has-unicode], otherwise it defaults to `Gauge.ascii`.
+ Details on the [theme object](#theme-objects) are documented elsewhere.
+* template: see [documentation elsewhere](#template-objects) for
+ defaults and details.
+
+[has-unicode]: https://www.npmjs.com/package/has-unicode
+
+If **ansiStream** isn't passed in, then one will be constructed from stderr
+with `ansi(process.stderr)`.
+
+### `gauge.show([name, [completed]])`
+
+* **name** – *(optional)* The name of the current thing contributing to progress. Defaults to the last value used, or "".
+* **completed** – *(optional)* The portion completed as a value between 0 and 1. Defaults to the last value used, or 0.
+
+If `process.stdout.isTTY` is false then this does nothing. If completed is 0
+and `gauge.pulse` has never been called, then similarly nothing will be printed.
+
+If `maxUpdateFrequency` msec haven't passed since the last call to `show` or
+`pulse` then similarly, nothing will be printed. (Actually, the update is
+deferred until `maxUpdateFrequency` msec have passed and if nothing else has
+happened, the gauge update will happen.)
+
+### `gauge.hide()`
+
+Removes the gauge from the terminal.
+
+### `gauge.pulse([name])`
+
+* **name** – *(optional)* The specific thing that triggered this pulse
+
+Spins the spinner in the gauge to show output. If **name** is included then
+it will be combined with the last name passed to `gauge.show` using the
+subsection property of the theme (typically a right facing arrow).
+
+### `gauge.disable()`
+
+Hides the gauge and ignores further calls to `show` or `pulse`.
+
+### `gauge.enable()`
+
+Shows the gauge and resumes updating when `show` or `pulse` is called.
+
+### `gauge.setTheme(theme)`
+
+Change the active theme, will be displayed with the next show or pulse
+
+### `gauge.setTemplate(template)`
+
+Change the active template, will be displayed with the next show or pulse
+
+### Theme Objects
+
+There are two theme objects available as a part of the module, `Gauge.unicode` and `Gauge.ascii`.
+Theme objects have the follow properties:
+
+| Property | Unicode | ASCII |
+| ---------- | ------- | ----- |
+| startgroup | ╢ | \| |
+| endgroup | ╟ | \| |
+| complete | █ | # |
+| incomplete | ░ | - |
+| spinner | ▀▐▄▌ | -\\\|/ |
+| subsection | → | -> |
+
+*startgroup*, *endgroup* and *subsection* can be as many characters as you want.
+
+*complete* and *incomplete* should be a single character width each.
+
+*spinner* is a list of characters to use in turn when displaying an activity
+spinner. The Gauge will spin as many characters as you give here.
+
+### Template Objects
+
+A template is an array of objects and strings that, after being evaluated,
+will be turned into the gauge line. The default template is:
+
+```javascript
+[
+ {type: "name", separated: true, maxLength: 25, minWidth: 25, align: "left"},
+ {type: "spinner", separated: true},
+ {type: "startgroup"},
+ {type: "completionbar"},
+ {type: "endgroup"}
+]
+```
+
+The various template elements can either be **plain strings**, in which case they will
+be be included verbatum in the output.
+
+If the template element is an object, it can have the following keys:
+
+* *type* can be:
+ * `name` – The most recent name passed to `show`; if this is in response to a
+ `pulse` then the name passed to `pulse` will be appended along with the
+ subsection property from the theme.
+ * `spinner` – If you've ever called `pulse` this will be one of the characters
+ from the spinner property of the theme.
+ * `startgroup` – The `startgroup` property from the theme.
+ * `completionbar` – This progress bar itself
+ * `endgroup` – The `endgroup` property from the theme.
+* *separated* – If true, the element will be separated with spaces from things on
+ either side (and margins count as space, so it won't be indented), but only
+ if its included.
+* *maxLength* – The maximum length for this element. If its value is longer it
+ will be truncated.
+* *minLength* – The minimum length for this element. If its value is shorter it
+ will be padded according to the *align* value.
+* *align* – (Default: left) Possible values "left", "right" and "center". Works
+ as you'd expect from word processors.
+* *length* – Provides a single value for both *minLength* and *maxLength*. If both
+ *length* and *minLength or *maxLength* are specifed then the latter take precedence.
+
+### Tracking Completion
+
+If you have more than one thing going on that you want to track completion
+of, you may find the related [are-we-there-yet] helpful. It's `change`
+event can be wired up to the `show` method to get a more traditional
+progress bar interface.
+
+[are-we-there-yet]: https://www.npmjs.com/package/are-we-there-yet
diff --git a/node_modules/gauge/example.png b/node_modules/gauge/example.png
new file mode 100644
index 000000000..2667cac45
--- /dev/null
+++ b/node_modules/gauge/example.png
Binary files differ
diff --git a/node_modules/gauge/package.json b/node_modules/gauge/package.json
new file mode 100644
index 000000000..ba69205a3
--- /dev/null
+++ b/node_modules/gauge/package.json
@@ -0,0 +1,83 @@
+{
+ "_args": [
+ [
+ "gauge@~1.2.0",
+ "/Users/rebecca/code/npm/node_modules/npmlog"
+ ]
+ ],
+ "_from": "gauge@>=1.2.0 <1.3.0",
+ "_id": "gauge@1.2.0",
+ "_inCache": true,
+ "_location": "/gauge",
+ "_nodeVersion": "1.1.0",
+ "_npmUser": {
+ "email": "me@re-becca.org",
+ "name": "iarna"
+ },
+ "_npmVersion": "2.6.0",
+ "_phantomChildren": {},
+ "_requested": {
+ "name": "gauge",
+ "raw": "gauge@~1.2.0",
+ "rawSpec": "~1.2.0",
+ "scope": null,
+ "spec": ">=1.2.0 <1.3.0",
+ "type": "range"
+ },
+ "_requiredBy": [
+ "/npmlog"
+ ],
+ "_resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.0.tgz",
+ "_shasum": "3094ab1285633f799814388fc8f2de67b4c012c5",
+ "_shrinkwrap": null,
+ "_spec": "gauge@~1.2.0",
+ "_where": "/Users/rebecca/code/npm/node_modules/npmlog",
+ "author": {
+ "email": "me@re-becca.org",
+ "name": "Rebecca Turner"
+ },
+ "bugs": {
+ "url": "https://github.com/iarna/gauge/issues"
+ },
+ "dependencies": {
+ "ansi": "^0.3.0",
+ "has-unicode": "^1.0.0",
+ "lodash.pad": "^3.0.0",
+ "lodash.padleft": "^3.0.0",
+ "lodash.padright": "^3.0.0"
+ },
+ "description": "A terminal based horizontal guage",
+ "devDependencies": {
+ "tap": "^0.4.13"
+ },
+ "directories": {},
+ "dist": {
+ "shasum": "3094ab1285633f799814388fc8f2de67b4c012c5",
+ "tarball": "http://registry.npmjs.org/gauge/-/gauge-1.2.0.tgz"
+ },
+ "gitHead": "db15c35374816b3fc3b9e1e54866f31ed7f4a733",
+ "homepage": "https://github.com/iarna/gauge",
+ "keywords": [
+ "gauge",
+ "progress",
+ "progressbar"
+ ],
+ "license": "ISC",
+ "main": "progress-bar.js",
+ "maintainers": [
+ {
+ "name": "iarna",
+ "email": "me@re-becca.org"
+ }
+ ],
+ "name": "gauge",
+ "optionalDependencies": {},
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/iarna/gauge"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "version": "1.2.0"
+}
diff --git a/node_modules/gauge/progress-bar.js b/node_modules/gauge/progress-bar.js
new file mode 100644
index 000000000..39dbf2ac4
--- /dev/null
+++ b/node_modules/gauge/progress-bar.js
@@ -0,0 +1,209 @@
+"use strict"
+var hasUnicode = require("has-unicode")
+var ansi = require("ansi")
+var align = {
+ center: require("lodash.pad"),
+ left: require("lodash.padright"),
+ right: require("lodash.padleft")
+}
+var defaultStream = process.stderr
+function isTTY() {
+ return process.stderr.isTTY
+}
+function getWritableTTYColumns() {
+ // One less than the actual as writing to the final column wraps the line
+ return process.stderr.columns - 1
+}
+
+var ProgressBar = module.exports = function (options, cursor) {
+ if (! options) options = {}
+ if (! cursor && options.write) {
+ cursor = options
+ options = {}
+ }
+ if (! cursor) {
+ cursor = ansi(defaultStream)
+ }
+ this.cursor = cursor
+ this.showing = false
+ this.theme = options.theme || (hasUnicode() ? ProgressBar.unicode : ProgressBar.ascii)
+ this.template = options.template || [
+ {type: "name", separated: true, length: 25},
+ {type: "spinner", separated: true},
+ {type: "startgroup"},
+ {type: "completionbar"},
+ {type: "endgroup"}
+ ]
+ this.updatefreq = options.maxUpdateFrequency || 50
+ this.lastName = ""
+ this.lastCompleted = 0
+ this.spun = 0
+ this.last = new Date(0)
+}
+ProgressBar.prototype = {}
+
+ProgressBar.unicode = {
+ startgroup: "╢",
+ endgroup: "╟",
+ complete: "█",
+ incomplete: "░",
+ spinner: "▀▐▄▌",
+ subsection: "→"
+}
+
+ProgressBar.ascii = {
+ startgroup: "|",
+ endgroup: "|",
+ complete: "#",
+ incomplete: "-",
+ spinner: "-\\|/",
+ subsection: "->"
+}
+
+ProgressBar.prototype.setTheme = function(theme) {
+ this.theme = theme
+}
+
+ProgressBar.prototype.setTemplate = function(template) {
+ this.template = template
+}
+
+ProgressBar.prototype.disable = function() {
+ this.hide()
+ this.disabled = true
+}
+
+ProgressBar.prototype.enable = function() {
+ this.disabled = false
+ this.show()
+}
+
+ProgressBar.prototype.hide = function() {
+ if (!isTTY()) return
+ if (this.disabled) return
+ this.cursor.show()
+ if (this.showing) this.cursor.up(1)
+ this.cursor.horizontalAbsolute(0).eraseLine()
+ this.showing = false
+}
+
+var repeat = function (str, count) {
+ var out = ""
+ for (var ii=0; ii<count; ++ii) out += str
+ return out
+}
+
+ProgressBar.prototype.pulse = function(name) {
+ ++ this.spun
+ if (! this.showing) return
+ if (this.disabled) return
+
+ var baseName = this.lastName
+ name = name
+ ? ( baseName
+ ? baseName + " " + this.theme.subsection + " " + name
+ : null )
+ : baseName
+ this.show(name)
+ this.lastName = baseName
+}
+
+ProgressBar.prototype.show = function(name, completed) {
+ name = this.lastName = name || this.lastName
+ completed = this.lastCompleted = completed || this.lastCompleted
+
+ if (!isTTY()) return
+ if (this.disabled) return
+ if (! this.spun && ! completed) return
+ if (this.tryAgain) {
+ clearTimeout(this.tryAgain)
+ this.tryAgain = null
+ }
+ var self = this
+ if (this.showing && new Date() - this.last < this.updatefreq) {
+ this.tryAgain = setTimeout(function () {
+ if (self.disabled) return
+ if (! self.spun && ! completed) return
+ drawBar()
+ }, this.updatefreq - (new Date() - this.last))
+ return
+ }
+
+ return drawBar()
+
+ function drawBar() {
+ var values = {
+ name: name,
+ spinner: self.spun,
+ completed: completed
+ }
+
+ self.last = new Date()
+
+ var statusline = self.renderTemplate(self.theme, self.template, values)
+
+ if (self.showing) self.cursor.up(1)
+ self.cursor
+ .hide()
+ .horizontalAbsolute(0)
+ .write(statusline.substr(0, getWritableTTYColumns()) + "\n")
+ .show()
+
+ self.showing = true
+ }
+}
+
+ProgressBar.prototype.renderTemplate = function (theme, template, values) {
+ values.startgroup = theme.startgroup
+ values.endgroup = theme.endgroup
+ values.spinner = values.spinner
+ ? theme.spinner.substr(values.spinner % theme.spinner.length,1)
+ : ""
+
+ var output = {prebar: "", postbar: ""}
+ var status = "prebar"
+ var self = this
+ template.forEach(function(T) {
+ if (typeof T === "string") {
+ output[status] += T
+ return
+ }
+ if (T.type === "completionbar") {
+ status = "postbar"
+ return
+ }
+ if (!values.hasOwnProperty(T.type)) throw new Error("Unknown template value '"+T.type+"'")
+ var value = self.renderValue(T, values[T.type])
+ if (value === "") return
+ var sofar = output[status].length
+ var lastChar = sofar ? output[status][sofar-1] : null
+ if (T.separated && sofar && lastChar !== " ") {
+ output[status] += " "
+ }
+ output[status] += value
+ if (T.separated) output[status] += " "
+ })
+
+ var bar = ""
+ if (status === "postbar") {
+ var nonBarLen = output.prebar.length + output.postbar.length
+
+ var barLen = getWritableTTYColumns() - nonBarLen
+ var sofar = Math.round(barLen * Math.max(0,Math.min(1,values.completed||0)))
+ var rest = barLen - sofar
+ bar = repeat(theme.complete, sofar)
+ + repeat(theme.incomplete, rest)
+ }
+
+ return output.prebar + bar + output.postbar
+}
+ProgressBar.prototype.renderValue = function (template, value) {
+ if (value == null || value === "") return ""
+ var maxLength = template.maxLength || template.length
+ var minLength = template.minLength || template.length
+ var alignWith = align[template.align] || align.left
+// if (maxLength) value = value.substr(-1 * maxLength)
+ if (maxLength) value = value.substr(0, maxLength)
+ if (minLength) value = alignWith(value, minLength)
+ return value
+}
diff --git a/node_modules/gauge/test/progress-bar.js b/node_modules/gauge/test/progress-bar.js
new file mode 100644
index 000000000..8e2a5ad64
--- /dev/null
+++ b/node_modules/gauge/test/progress-bar.js
@@ -0,0 +1,148 @@
+"use strict"
+var test = require("tap").test
+var ProgressBar = require("../progress-bar.js")
+
+var cursor = []
+var C
+var bar = new ProgressBar({theme: ProgressBar.ascii}, C = {
+ show: function () {
+ cursor.push(["show"])
+ return C
+ },
+ hide: function () {
+ cursor.push(["hide"])
+ return C
+ },
+ up: function (lines) {
+ cursor.push(["up",lines])
+ return C
+ },
+ horizontalAbsolute: function (col) {
+ cursor.push(["horizontalAbsolute", col])
+ return C
+ },
+ eraseLine: function () {
+ cursor.push(["eraseLine"])
+ return C
+ },
+ write: function (line) {
+ cursor.push(["write", line])
+ return C
+ }
+})
+
+
+function isOutput(t, msg, output) {
+ var tests = []
+ for (var ii = 0; ii<output.length; ++ii) {
+ for (var jj = 0; jj<output[ii].length; ++jj) {
+ tests.push({cmd: ii, arg: jj})
+ }
+ }
+ tests.forEach(function(test) {
+ t.is(cursor[test.cmd] ? cursor[test.cmd][test.arg] : null,
+ output[test.cmd][test.arg],
+ msg + ": " + output[test.cmd] + (test.arg ? " arg #"+test.arg : ""))
+ })
+}
+
+test("hide", function (t) {
+ t.plan(11)
+ process.stderr.isTTY = false
+ bar.hide()
+ t.is(cursor.length, 0, "We don't progress bar without a tty")
+ cursor = []
+ process.stderr.isTTY = true
+ bar.hide()
+ isOutput(t, "hide while not showing",[
+ ["show"], // cursor
+ ["horizontalAbsolute",0],
+ ["eraseLine"]])
+ cursor = []
+ bar.showing = true
+ bar.hide()
+ isOutput(t, "hide while showing",[
+ ["show"], // cursor
+ ["up", 1],
+ ["horizontalAbsolute",0],
+ ["eraseLine"]])
+})
+
+test("renderTemplate", function (t) {
+ t.plan(16)
+ process.stderr.columns = 11
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "name"}],{name: "NAME"})
+ t.is(result, "NAME", "name substitution")
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 0})
+ t.is(result, "----------", "0% bar")
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 0.5})
+ t.is(result, "#####-----", "50% bar")
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 1})
+ t.is(result, "##########", "100% bar")
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: -100})
+ t.is(result, "----------", "0% underflow bar")
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "completionbar"}],{completed: 100})
+ t.is(result, "##########", "100% overflow bar")
+ var result = bar.renderTemplate(ProgressBar.ascii,[{type: "name"},{type: "completionbar"}],{name: "NAME", completed: 0.5})
+ t.is(result, "NAME###---", "name + 50%")
+ var result = bar.renderTemplate(ProgressBar.ascii, ["static"], {})
+ t.is(result, "static", "static text")
+ var result = bar.renderTemplate(ProgressBar.ascii, ["static",{type: "name"}], {name: "NAME"})
+ t.is(result, "staticNAME", "static text + var")
+ var result = bar.renderTemplate(ProgressBar.ascii, ["static",{type: "name", separated: true}], {name: "NAME"})
+ t.is(result, "static NAME ", "pre-separated")
+ var result = bar.renderTemplate(ProgressBar.ascii, [{type: "name", separated: true}, "static"], {name: "NAME"})
+ t.is(result, "NAME static", "post-separated")
+ var result = bar.renderTemplate(ProgressBar.ascii, ["1",{type: "name", separated: true}, "2"], {name: ""})
+ t.is(result, "12", "separated no value")
+ var result = bar.renderTemplate(ProgressBar.ascii, ["1",{type: "name", separated: true}, "2"], {name: "NAME"})
+ t.is(result, "1 NAME 2", "separated value")
+ var result = bar.renderTemplate(ProgressBar.ascii, [{type: "spinner"}], {spinner: 0})
+ t.is(result, "", "No spinner")
+ var result = bar.renderTemplate(ProgressBar.ascii, [{type: "spinner"}], {spinner: 1})
+ t.is(result, "\\", "Spinner 1")
+ var result = bar.renderTemplate(ProgressBar.ascii, [{type: "spinner"}], {spinner: 10})
+ t.is(result, "|", "Spinner 10")
+})
+
+test("show & pulse", function (t) {
+ t.plan(23)
+
+ process.stderr.columns = 16
+ cursor = []
+ process.stderr.isTTY = false
+ bar.template[0].length = 6
+ bar.last = new Date(0)
+ bar.show("NAME", 0)
+ t.is(cursor.length, 0, "no tty, no progressbar")
+
+ cursor = []
+ process.stderr.isTTY = true
+ bar.last = new Date(0)
+ bar.show("NAME", 0.1)
+ isOutput(t, "tty, name, completion",
+ [ [ 'hide' ],
+ [ 'horizontalAbsolute', 0 ],
+ [ 'write', 'NAME |#-----|\n' ],
+ [ 'show' ] ])
+
+ bar.show("S")
+ cursor = []
+ bar.last = new Date(0)
+ bar.pulse()
+ isOutput(t, "pulsed spinner",
+ [ [ 'up', 1 ],
+ [ 'hide' ],
+ [ 'horizontalAbsolute', 0 ],
+ [ 'write', 'S \\ |----|\n' ],
+ [ 'show' ] ])
+ cursor = []
+ bar.last = new Date(0)
+ bar.pulse("P")
+ isOutput(t, "pulsed spinner with subsection",
+ [ [ 'up', 1 ],
+ [ 'hide' ],
+ [ 'horizontalAbsolute', 0 ],
+ [ 'write', 'S -> P | |----|\n' ],
+ [ 'show' ] ])
+})