From c04c1d73b30979d04d94398309ee47643ede0af4 Mon Sep 17 00:00:00 2001 From: David da Silva Date: Mon, 23 May 2016 07:01:41 +0200 Subject: [PATCH] Make CI run browser tests (#2231) * Initial prep for browser tests in CI - :arrow_up: browserify@13.0.0 Some fixes that we didn't have were required. - :bug: Fix browser not being able to require describe/it `support/browser-entry.js` was removing the listener that is in charge of keeping `Mocha.describe/it/suite` etc up-to-date. That listener is now added everytime a `ui` is set up. - Correct isatty for browser * Travis + SauceLabs + Karma setup (first pass) - add sauce connect - prepare to use karma on saucelabs; fix potential windows problems - rewrite `scripts/ensure-compatible-npm.sh` in JS - detect travis node 0.8 env; just upgrade if found - symlink `mocha` to itself for `karma-mocha` - if explicit `--production` flag is present, skip this - don't know how to skip this part if `mocha` is a devDep of some other package - use phantomjs@1.9.19; don't try to install npm@3 - browser tests with karma & phantom - move `support/browser-entry.js` to `browser-entry.js` to keep paths sane - `karma.conf.js` loads data out of `.karma.conf.js` - we have a "main" browser suite - then we have suites for each interface - each suite is a single run of Karma - each suite is executed by the `Makefile` - build `./mocha.js` upon test execution for `karma-mocha` to use - bonus: 3rd-party browserification should theoretically now be possible as per the `./index.js` entry in `package.json`'s `browser` field - add dev deps for karma - test changes: - split `lookupFiles` test into its own file so we can ignore it in Karma - fix broken `test/acceptance/throw.js` for browser - fix `test/acceptance/utils.js`'s `type` tests for PhantomJS - try to reduce build matrix - fix missing targets - fix infinite loop in Makefile - downgrade phantomjs to 1.9.8 - remove some cruft from karma config; try to add sauce labs - try again w/ the saucelabs - typo - remove karma-source-map-support as it's a no-go on IE8 - Require up-to-date mocha.js for any browser tests - Make CI rebuild mocha.js. Make won't rebuild when just checked out by CI because timestamps on source and mocha.js are the same. We could use a script to set the timestamps to the commit time, but it still wouldn't work if mocha.js were committed along with other changes that hadn't been built into it. Which shouldn't happen anyway -- but then again, the point of CI is to see what commits change, it's usually going to need to rebuild mocha.js if it's working right, so it's not going to hurt much to rebuild it every time even on the few times it doesn't need to. * fix IE8 compatibility for browser tests - Avoid `Array.prototype.map` in test - Workaround for missing `Object.create` - Use a shim for `Date.prototype.toISOString` - Use simple number math instead of array indexing for interface tests - Use `expect` instead of `should` - Avoid builtin function in stringify test (A quick check revealed that stringify does not treat toString specially anyway, and IE8 ignores the toString assigned to the object, so use a different property name) - Use `karma-expect` for automatic browser tests - Remove `karma-should` * Travis + SauceLabs + Karma setup (second pass) - add note about exporting `global` in `browser-entry.js` - remove too-short timeout for "throw" unit tests (because SauceLabs) - revert modification to `isatty()` function of `lib/browser/tty.js` - switch reporter to `karma-spec-reporter` - use custom `karma-no-mocha` package - fixtures in `test/browser-fixtures/` - use single `karma.conf.js` --- .travis.yml | 37 +- CHANGELOG.md | 8 + Makefile | 50 +- support/browser-entry.js => browser-entry.js | 7 +- karma.conf.js | 97 + lib/mocha.js | 33 +- lib/utils.js | 10 +- mocha.js | 8967 +++++++++--------- package.json | 23 +- scripts/ensure-compatible-npm.sh | 13 - scripts/upgrade-npm.js | 21 + test/acceptance/context.js | 18 +- test/acceptance/http.js | 2 +- test/acceptance/interfaces/bdd.js | 36 +- test/acceptance/interfaces/exports.js | 12 +- test/acceptance/interfaces/qunit.js | 18 +- test/acceptance/interfaces/tdd.js | 33 +- test/acceptance/lookup-files.js | 56 + test/acceptance/misc/only/bdd.js | 6 +- test/acceptance/misc/only/tdd.js | 6 +- test/acceptance/require/require.js | 8 +- test/acceptance/root.js | 2 +- test/acceptance/test.coffee | 2 +- test/acceptance/throw.js | 37 +- test/acceptance/utils.js | 240 +- test/browser-fixtures/bdd.js | 4 + test/browser-fixtures/exports.js | 4 + test/browser-fixtures/qunit.js | 4 + test/browser-fixtures/tdd.js | 4 + test/fixture-expect.js | 1 + test/mocha.opts | 1 + 31 files changed, 5143 insertions(+), 4617 deletions(-) rename support/browser-entry.js => browser-entry.js (93%) create mode 100644 karma.conf.js delete mode 100755 scripts/ensure-compatible-npm.sh create mode 100644 scripts/upgrade-npm.js create mode 100644 test/acceptance/lookup-files.js create mode 100644 test/browser-fixtures/bdd.js create mode 100644 test/browser-fixtures/exports.js create mode 100644 test/browser-fixtures/qunit.js create mode 100644 test/browser-fixtures/tdd.js create mode 100644 test/fixture-expect.js diff --git a/.travis.yml b/.travis.yml index ffd19c6b50..9101c6ea02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,22 +8,37 @@ dist: trusty language: node_js -node_js: - - '6' - - '5' - - '4' - - 'iojs' - - '0.12' - - '0.11' - - '0.10' - - '0.8' +matrix: + include: + - node_js: '6' + env: TARGET="clean lint test-node test-browser" + - node_js: '5' + env: TARGET=test-node + - node_js: '4' + env: TARGET=test-node + - node_js: 'iojs' + env: TARGET=test-node + - node_js: '0.12' + env: TARGET=test-node + - node_js: '0.11' + env: TARGET=test-node + - node_js: '0.10' + env: TARGET=test-node + - node_js: '0.8' + env: TARGET=test-node before_install: # node 0.8 won't install our dev deps with an out-of-box npm; # this upgrades it - - ./scripts/ensure-compatible-npm.sh + - node ./scripts/upgrade-npm.js -script: travis_retry npm test +script: travis_retry make $TARGET + +addons: + sauce_connect: + username: mochajs + access_key: + secure: R0HXKtR6F2iDEnItv57BTRyL64XfyIlyyluPLK8G33O/InaQjT3KxGuxevz3nVYIqqnI1MPjYodXcQaqrBOLUVmA2vhBeMHB2OwGc9GAL+HBtB1fh+bQJelkl/XMcTTbC5LIZ6nZjmFnkmjqT3AmUhdDRISgieIFeVY4x48LfiU= notifications: urls: diff --git a/CHANGELOG.md b/CHANGELOG.md index 199deaf47b..a644e93a9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Unreleased +================== + +* [#2079], [#2231] - Add browser to CI + +[#2079]: https://github.com/mochajs/mocha/issues/2079 +[#2231]: https://github.com/mochajs/mocha/pull/2231 + 2.4.5 / 2016-01-28 ================== diff --git a/Makefile b/Makefile index 28e6c87f6f..2288ae862e 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,18 @@ BROWSERIFY := node_modules/.bin/browserify ESLINT := node_modules/.bin/eslint +KARMA := node_modules/.bin/karma REPORTER ?= spec TM_BUNDLE = JavaScript\ mocha.tmbundle SRC = $(shell find lib -name "*.js" -type f | sort) +TESTS = $(shell find test -name "*.js" -type f | sort) SUPPORT = $(wildcard support/*.js) all: mocha.js mocha.js: $(SRC) $(SUPPORT) - @$(BROWSERIFY) ./support/browser-entry \ + @printf "==> [Browser :: build]\n" + @$(BROWSERIFY) ./browser-entry \ --ignore 'fs' \ --ignore 'glob' \ --ignore 'jade' \ @@ -18,29 +21,53 @@ mocha.js: $(SRC) $(SUPPORT) --exclude './lib-cov/mocha' > $@ clean: + @printf "==> [Clean]\n" rm -f mocha.js rm -rf test-outputs - rm -fr lib-cov + rm -rf lib-cov rm -f coverage.html test-cov: lib-cov + @printf "==> [Test :: Coverage]\n" @COV=1 $(MAKE) test REPORTER=html-cov > coverage.html lib-cov: + @printf "==> [Coverage]\n" @rm -fr ./$@ @jscoverage lib $@ lint: + @printf "==> [Test :: Lint]\n" @$(ESLINT) $(SRC) -test: lint test-unit +test-node: test-bdd test-tdd test-qunit test-exports test-unit test-integration test-jsapi test-compilers test-glob test-requires test-reporters test-only -test-all: lint test-bdd test-tdd test-qunit test-exports test-unit test-integration test-jsapi test-compilers test-glob test-requires test-reporters test-only +test-browser: test-browser-unit test-browser-bdd test-browser-qunit test-browser-tdd test-browser-exports + +test: lint test-node test-browser + +test-browser-unit: mocha.js + @printf "==> [Test :: Browser]\n" + @NODE_PATH=. $(KARMA) start + +test-browser-bdd: + @printf "==> [Test :: Browser :: BDD]\n" + @MOCHA_UI=bdd $(MAKE) test-browser-unit + +test-browser-qunit: + @printf "==> [Test :: Browser :: QUnit]\n" + @MOCHA_UI=qunit $(MAKE) test-browser-unit + +test-browser-tdd: + @printf "==> [Test :: Browser :: TDD]\n" + @MOCHA_UI=tdd $(MAKE) test-browser-unit test-jsapi: + @printf "==> [Test :: JS API]\n" @node test/jsapi test-unit: + @printf "==> [Test :: Unit]\n" @./bin/mocha \ --reporter $(REPORTER) \ test/acceptance/*.js \ @@ -48,11 +75,13 @@ test-unit: test/*.js test-integration: + @printf "==> [Test :: Integrations]\n" @./bin/mocha \ --reporter $(REPORTER) \ test/integration/*.js test-compilers: + @printf "==> [Test :: Compilers]\n" @./bin/mocha \ --reporter $(REPORTER) \ --compilers coffee:coffee-script/register,foo:./test/compiler/foo \ @@ -60,6 +89,7 @@ test-compilers: test/acceptance/test.foo test-requires: + @printf "==> [Test :: Requires]\n" @./bin/mocha \ --reporter $(REPORTER) \ --compilers coffee:coffee-script/register \ @@ -70,38 +100,45 @@ test-requires: test/acceptance/require/require.js test-bdd: + @printf "==> [Test :: BDD]\n" @./bin/mocha \ --reporter $(REPORTER) \ --ui bdd \ test/acceptance/interfaces/bdd test-tdd: + @printf "==> [Test :: TDD]\n" @./bin/mocha \ --reporter $(REPORTER) \ --ui tdd \ test/acceptance/interfaces/tdd test-qunit: + @printf "==> [Test :: QUnit]\n" @./bin/mocha \ --reporter $(REPORTER) \ --ui qunit \ test/acceptance/interfaces/qunit test-exports: + @printf "==> [Test :: Exports]\n" @./bin/mocha \ --reporter $(REPORTER) \ --ui exports \ test/acceptance/interfaces/exports test-glob: + @printf "==> [Test :: Glob]\n" @./test/acceptance/glob/glob.sh test-reporters: + @printf "==> [Test :: Reporters]\n" @./bin/mocha \ --reporter $(REPORTER) \ test/reporters/*.js test-only: + @printf "==> [Test :: Only]\n" @./bin/mocha \ --reporter $(REPORTER) \ --ui tdd \ @@ -123,11 +160,13 @@ test-only: test/acceptance/misc/only/qunit test-mocha: + @printf "==> [Test :: Mocha]\n" @./bin/mocha \ --reporter $(REPORTER) \ test/mocha non-tty: + @printf "==> [Test :: Non-TTY]\n" @./bin/mocha \ --reporter dot \ test/acceptance/interfaces/bdd 2>&1 > /tmp/dot.out @@ -150,6 +189,7 @@ non-tty: @cat /tmp/spec.out tm: + @printf "==> [TM]\n" @open editors/$(TM_BUNDLE) -.PHONY: test-cov test-jsapi test-compilers watch test test-all test-bdd test-tdd test-qunit test-exports test-unit test-integration non-tty tm clean +.PHONY: test-cov test-jsapi test-compilers watch test test-node test-bdd test-tdd test-qunit test-exports test-unit test-integration non-tty tm clean test-browser test-browser-unit test-browser-bdd test-browser-qunit test-browser-tdd test-browser-exports lint diff --git a/support/browser-entry.js b/browser-entry.js similarity index 93% rename from support/browser-entry.js rename to browser-entry.js index 8fe9f7828f..27ea71f514 100644 --- a/support/browser-entry.js +++ b/browser-entry.js @@ -4,7 +4,7 @@ process.stdout = require('browser-stdout')(); -var Mocha = require('../'); +var Mocha = require('./lib/mocha'); /** * Create a Mocha instance. @@ -159,3 +159,8 @@ Mocha.process = process; global.Mocha = Mocha; global.mocha = mocha; + +// this allows test/acceptance/required-tokens.js to pass; thus, +// you can now do `const describe = require('mocha').describe` in a +// browser context (assuming browserification). should fix #880 +module.exports = global; diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000000..c1a9ffd7f1 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,97 @@ +'use strict'; + +module.exports = function(config) { + var cfg = { + frameworks: [ + 'browserify', + 'expect', + 'mocha' + ], + files: [ + 'test/browser-fixtures/bdd.js', + 'test/acceptance/*.js' + ], + exclude: [ + 'test/acceptance/http.js', + 'test/acceptance/fs.js', + 'test/acceptance/lookup-files.js', + 'test/acceptance/require/**/*.js', + 'test/acceptance/misc/**/*.js' + ], + preprocessors: { + 'test/**/*.js': ['browserify'] + }, + browserify: { + debug: true, + configure: function configure(b) { + b.ignore('glob') + .ignore('jade') + .ignore('supports-color') + .exclude('./lib-cov/mocha'); + } + }, + reporters: ['spec'], + colors: true, + browsers: ['PhantomJS'], + logLevel: config.LOG_INFO, + singleRun: true + }; + + // see https://github.com/saucelabs/karma-sauce-example + // TO RUN LOCALLY: + // Execute `CI=1 make test-browser`, once you've set the SAUCE_USERNAME and + // SAUCE_ACCESS_KEY env vars. + if (process.env.CI) { + if (!(process.env.SAUCE_USERNAME || process.env.SAUCE_ACCESS_KEY)) { + throw new Error('Must set SAUCE_USERNAME and SAUCE_ACCESS_KEY ' + + 'environment variables!'); + } + cfg.reporters.push('saucelabs'); + cfg.browsers.push('ie8'); + cfg.customLaunchers = { + ie8: { + base: 'SauceLabs', + browserName: 'internet explorer', + platform: 'Windows XP', + version: '8.0' + } + }; + + cfg.sauceLabs = { + public: 'public' + }; + + if (process.env.TRAVIS) { + // correlate build/tunnel with Travis + cfg.sauceLabs.build = 'TRAVIS #' + process.env.TRAVIS_BUILD_NUMBER + + ' (' + process.env.TRAVIS_BUILD_ID + ')'; + cfg.sauceLabs.tunnelIdentifier = process.env.TRAVIS_JOB_NUMBER; + cfg.sauceLabs.startConnect = false; + } else { + // otherwise just make something up + cfg.sauceLabs.build = require('os').hostname() + ' (' + Date.now() + ')'; + } + + // for slow browser booting, ostensibly + cfg.captureTimeout = 120000; + } + + // the MOCHA_UI env var will determine if we're running interface-specific + // tets. since you can only load one at a time, each must be run separately. + // each has its own set of acceptance tests and a fixture. + // the "bdd" fixture is used by default. + var ui = process.env.MOCHA_UI; + if (ui) { + if (cfg.sauceLabs) { + cfg.sauceLabs.testName = 'Interface "' + ui + '" integration tests'; + } + cfg.files = [ + 'test/browser-fixtures/' + ui + '.js', + 'test/acceptance/interfaces/' + ui + '.js' + ]; + } else if (cfg.sauceLabs) { + cfg.sauceLabs.testName = 'Unit Tests'; + } + + config.set(cfg); +}; diff --git a/lib/mocha.js b/lib/mocha.js index fc493d2d25..46775ab55c 100644 --- a/lib/mocha.js +++ b/lib/mocha.js @@ -99,22 +99,6 @@ function Mocha(options) { if (options.slow) { this.slow(options.slow); } - - this.suite.on('pre-require', function(context) { - exports.afterEach = context.afterEach || context.teardown; - exports.after = context.after || context.suiteTeardown; - exports.beforeEach = context.beforeEach || context.setup; - exports.before = context.before || context.suiteSetup; - exports.describe = context.describe || context.suite; - exports.it = context.it || context.test; - exports.setup = context.setup || context.beforeEach; - exports.suiteSetup = context.suiteSetup || context.before; - exports.suiteTeardown = context.suiteTeardown || context.after; - exports.suite = context.suite || context.describe; - exports.teardown = context.teardown || context.afterEach; - exports.test = context.test || context.it; - exports.run = context.run; - }); } /** @@ -202,6 +186,23 @@ Mocha.prototype.ui = function(name) { } } this._ui = this._ui(this.suite); + + this.suite.on('pre-require', function(context) { + exports.afterEach = context.afterEach || context.teardown; + exports.after = context.after || context.suiteTeardown; + exports.beforeEach = context.beforeEach || context.setup; + exports.before = context.before || context.suiteSetup; + exports.describe = context.describe || context.suite; + exports.it = context.it || context.test; + exports.setup = context.setup || context.beforeEach; + exports.suiteSetup = context.suiteSetup || context.before; + exports.suiteTeardown = context.suiteTeardown || context.after; + exports.suite = context.suite || context.describe; + exports.teardown = context.teardown || context.afterEach; + exports.test = context.test || context.it; + exports.run = context.run; + }); + return this; }; diff --git a/lib/utils.js b/lib/utils.js index 1ec27085fd..e5d214021c 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -12,6 +12,7 @@ var join = require('path').join; var readdirSync = require('fs').readdirSync; var statSync = require('fs').statSync; var watchFile = require('fs').watchFile; +var toISOString = require('to-iso-string'); /** * Ignored directories. @@ -479,9 +480,12 @@ function jsonStringify(object, spaces, depth) { : val.toString(); break; case 'date': - var sDate = isNaN(val.getTime()) // Invalid date - ? val.toString() - : val.toISOString(); + var sDate; + if (isNaN(val.getTime())) { // Invalid date + sDate = val.toString(); + } else { + sDate = val.toISOString ? val.toISOString() : toISOString(val); + } val = '[Date: ' + sDate + ']'; break; case 'buffer': diff --git a/mocha.js b/mocha.js index 19561978eb..9d98db7101 100644 --- a/mocha.js +++ b/mocha.js @@ -1,11 +1,171 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o

%e%ems

', test.speed, test.title, test.duration, url); - } else if (test.pending) { + } else if (test.isPending()) { el = fragment('
  • %e

  • ', test.title); } else { el = fragment('
  • %e

  • ', test.title, self.testURL(test)); @@ -2508,7 +2669,7 @@ function HTML(runner) { // toggle code // TODO: defer - if (!test.pending) { + if (!test.isPending()) { var h2 = el.getElementsByTagName('h2')[0]; on(h2, 'click', function() { @@ -2644,7 +2805,7 @@ function on(el, event, fn) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../browser/progress":4,"../utils":39,"./base":17,"escape-string-regexp":68}],22:[function(require,module,exports){ +},{"../browser/progress":4,"../utils":39,"./base":17,"escape-string-regexp":47}],22:[function(require,module,exports){ // Alias exports to a their normalized format Mocha#reporter to prevent a need // for dynamic (try/catch) requires, which Browserify doesn't handle. exports.Base = exports.base = require('./base'); @@ -2820,7 +2981,7 @@ function clean(test) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./base":17,"_process":51}],24:[function(require,module,exports){ +},{"./base":17,"_process":57}],24:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -2884,7 +3045,7 @@ function clean(test) { } }).call(this,require('_process')) -},{"./base":17,"_process":51}],25:[function(require,module,exports){ +},{"./base":17,"_process":57}],25:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -2978,7 +3139,7 @@ function errorJSON(err) { } }).call(this,require('_process')) -},{"./base":17,"_process":51}],26:[function(require,module,exports){ +},{"./base":17,"_process":57}],26:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3074,7 +3235,7 @@ function Landing(runner) { inherits(Landing, Base); }).call(this,require('_process')) -},{"../utils":39,"./base":17,"_process":51}],27:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57}],27:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3139,7 +3300,7 @@ function List(runner) { inherits(List, Base); }).call(this,require('_process')) -},{"../utils":39,"./base":17,"_process":51}],28:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57}],28:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3240,7 +3401,7 @@ function Markdown(runner) { } }).call(this,require('_process')) -},{"../utils":39,"./base":17,"_process":51}],29:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57}],29:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3280,7 +3441,7 @@ function Min(runner) { inherits(Min, Base); }).call(this,require('_process')) -},{"../utils":39,"./base":17,"_process":51}],30:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57}],30:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3545,7 +3706,7 @@ function write(string) { } }).call(this,require('_process')) -},{"../utils":39,"./base":17,"_process":51}],31:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57}],31:[function(require,module,exports){ (function (process){ /** * Module dependencies. @@ -3638,7 +3799,7 @@ function Progress(runner, options) { inherits(Progress, Base); }).call(this,require('_process')) -},{"../utils":39,"./base":17,"_process":51}],32:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57}],32:[function(require,module,exports){ /** * Module dependencies. */ @@ -3928,7 +4089,7 @@ XUnit.prototype.test = function(test) { if (test.state === 'failed') { var err = test.err; this.write(tag('testcase', attrs, false, tag('failure', {}, false, cdata(escape(err.message) + '\n' + err.stack)))); - } else if (test.pending) { + } else if (test.isPending()) { this.write(tag('testcase', attrs, false, tag('skipped', {}, true))); } else { this.write(tag('testcase', attrs, true)); @@ -3971,7 +4132,7 @@ function cdata(str) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../utils":39,"./base":17,"_process":51,"fs":41,"mkdirp":70,"path":41}],35:[function(require,module,exports){ +},{"../utils":39,"./base":17,"_process":57,"fs":43,"mkdirp":54,"path":43}],35:[function(require,module,exports){ (function (global){ /** * Module dependencies. @@ -4020,6 +4181,7 @@ module.exports = Runnable; function Runnable(title, fn) { this.title = title; this.fn = fn; + this.body = (fn || '').toString(); this.async = fn && fn.length; this.sync = !this.async; this._timeout = 2000; @@ -4029,6 +4191,7 @@ function Runnable(title, fn) { this._trace = new Error('done() called multiple times'); this._retries = -1; this._currentRetry = 0; + this.pending = false; } /** @@ -4099,12 +4262,21 @@ Runnable.prototype.enableTimeouts = function(enabled) { /** * Halt and mark as pending. * - * @api private + * @api public */ Runnable.prototype.skip = function() { throw new Pending(); }; +/** + * Check if this runnable or its parent suite is marked as pending. + * + * @api private + */ +Runnable.prototype.isPending = function() { + return this.pending || (this.parent && this.parent.isPending()); +}; + /** * Set number of retries. * @@ -4277,7 +4449,7 @@ Runnable.prototype.run = function(fn) { // sync or promise-returning try { - if (this.pending) { + if (this.isPending()) { done(); } else { callFn(this.fn); @@ -4838,12 +5010,7 @@ Runner.prototype.runTests = function(suite, fn) { return; } - function parentPending(suite) { - return suite.pending || (suite.parent && parentPending(suite.parent)); - } - - // pending - if (test.pending || parentPending(test.parent)) { + if (test.isPending()) { self.emit('pending', test); self.emit('test end', test); return next(); @@ -4852,7 +5019,7 @@ Runner.prototype.runTests = function(suite, fn) { // execute test and hook(s) self.emit('test', self.test = test); self.hookDown('beforeEach', function(err, errSuite) { - if (suite.pending) { + if (suite.isPending()) { self.emit('pending', test); self.emit('test end', test); return next(); @@ -5230,7 +5397,7 @@ function extraGlobals() { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./pending":16,"./runnable":35,"./utils":39,"_process":51,"debug":2,"events":3}],37:[function(require,module,exports){ +},{"./pending":16,"./runnable":35,"./utils":39,"_process":57,"debug":2,"events":3}],37:[function(require,module,exports){ /** * Module dependencies. */ @@ -5261,9 +5428,6 @@ exports = module.exports = Suite; exports.create = function(parent, title) { var suite = new Suite(title, parent.ctx); suite.parent = parent; - if (parent.pending) { - suite.pending = true; - } title = suite.fullTitle(); parent.addSuite(suite); return suite; @@ -5409,6 +5573,15 @@ Suite.prototype.bail = function(bail) { return this; }; +/** + * Check if this suite or its parent suite is marked as pending. + * + * @api private + */ +Suite.prototype.isPending = function() { + return this.pending || (this.parent && this.parent.isPending()); +}; + /** * Run `fn(test[, done])` before running tests. * @@ -5418,7 +5591,7 @@ Suite.prototype.bail = function(bail) { * @return {Suite} for chaining */ Suite.prototype.beforeAll = function(title, fn) { - if (this.pending) { + if (this.isPending()) { return this; } if (typeof title === 'function') { @@ -5448,7 +5621,7 @@ Suite.prototype.beforeAll = function(title, fn) { * @return {Suite} for chaining */ Suite.prototype.afterAll = function(title, fn) { - if (this.pending) { + if (this.isPending()) { return this; } if (typeof title === 'function') { @@ -5478,7 +5651,7 @@ Suite.prototype.afterAll = function(title, fn) { * @return {Suite} for chaining */ Suite.prototype.beforeEach = function(title, fn) { - if (this.pending) { + if (this.isPending()) { return this; } if (typeof title === 'function') { @@ -5508,7 +5681,7 @@ Suite.prototype.beforeEach = function(title, fn) { * @return {Suite} for chaining */ Suite.prototype.afterEach = function(title, fn) { - if (this.pending) { + if (this.isPending()) { return this; } if (typeof title === 'function') { @@ -5646,7 +5819,6 @@ function Test(title, fn) { Runnable.call(this, title, fn); this.pending = !fn; this.type = 'test'; - this.body = (fn || '').toString(); } /** @@ -5684,6 +5856,7 @@ var join = require('path').join; var readdirSync = require('fs').readdirSync; var statSync = require('fs').statSync; var watchFile = require('fs').watchFile; +var toISOString = require('to-iso-string'); /** * Ignored directories. @@ -6126,7 +6299,7 @@ function jsonStringify(object, spaces, depth) { var space = spaces * depth; var str = isArray(object) ? '[' : '{'; var end = isArray(object) ? ']' : '}'; - var length = object.length || exports.keys(object).length; + var length = typeof object.length === 'number' ? object.length : exports.keys(object).length; // `.repeat()` polyfill function repeat(s, n) { return new Array(n).join(s); @@ -6144,15 +6317,19 @@ function jsonStringify(object, spaces, depth) { break; case 'boolean': case 'regexp': + case 'symbol': case 'number': val = val === 0 && (1 / val) === -Infinity // `-0` ? '-0' : val.toString(); break; case 'date': - var sDate = isNaN(val.getTime()) // Invalid date - ? val.toString() - : val.toISOString(); + var sDate; + if (isNaN(val.getTime())) { // Invalid date + sDate = val.toString(); + } else { + sDate = val.toISOString ? val.toISOString() : toISOString(val); + } val = '[Date: ' + sDate + ']'; break; case 'buffer': @@ -6170,7 +6347,7 @@ function jsonStringify(object, spaces, depth) { } for (var i in object) { - if (!object.hasOwnProperty(i)) { + if (!Object.prototype.hasOwnProperty.call(object, i)) { continue; // not my business } --length; @@ -6269,6 +6446,7 @@ exports.canonicalize = function(value, stack) { case 'number': case 'regexp': case 'boolean': + case 'symbol': canonicalizedObj = value; break; default: @@ -6403,7 +6581,11 @@ exports.stackTraceFilter = function() { } // Clean up cwd(absolute) - list.push(line.replace(cwd, '')); + if (/\(?.+:\d+:\d+\)?$/.test(line)) { + line = line.replace(cwd, ''); + } + + list.push(line); return list; }, []); @@ -6412,57 +6594,169 @@ exports.stackTraceFilter = function() { }; }).call(this,require('_process'),require("buffer").Buffer) -},{"_process":51,"buffer":43,"debug":2,"fs":41,"glob":41,"path":41,"util":66}],40:[function(require,module,exports){ -(function (process){ -var WritableStream = require('stream').Writable -var inherits = require('util').inherits - -module.exports = BrowserStdout +},{"_process":57,"buffer":44,"debug":2,"fs":43,"glob":43,"path":43,"to-iso-string":70,"util":73}],40:[function(require,module,exports){ +'use strict' +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray -inherits(BrowserStdout, WritableStream) +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array -function BrowserStdout(opts) { - if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts) +function init () { + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i + } - opts = opts || {} - WritableStream.call(this, opts) - this.label = (opts.label !== undefined) ? opts.label : 'stdout' + revLookup['-'.charCodeAt(0)] = 62 + revLookup['_'.charCodeAt(0)] = 63 } -BrowserStdout.prototype._write = function(chunks, encoding, cb) { - var output = chunks.toString ? chunks.toString() : chunks - if (this.label === false) { - console.log(output) - } else { - console.log(this.label+':', output) +init() + +function toByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + var len = b64.length + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') } - process.nextTick(cb) -} -}).call(this,require('_process')) -},{"_process":51,"stream":63,"util":66}],41:[function(require,module,exports){ + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + placeHolders = b64[len - 2] === '=' ? 2 : b64[len - 1] === '=' ? 1 : 0 -},{}],42:[function(require,module,exports){ -arguments[4][41][0].apply(exports,arguments) -},{"dup":41}],43:[function(require,module,exports){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(len * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? len - 4 : len + + var L = 0 + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] + arr[L++] = (tmp >> 16) & 0xFF + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + if (placeHolders === 2) { + tmp = (revLookup[b64.charCodeAt(i)] << 2) | (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[L++] = tmp & 0xFF + } else if (placeHolders === 1) { + tmp = (revLookup[b64.charCodeAt(i)] << 10) | (revLookup[b64.charCodeAt(i + 1)] << 4) | (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[L++] = (tmp >> 8) & 0xFF + arr[L++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var output = '' + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength))) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + output += lookup[tmp >> 2] + output += lookup[(tmp << 4) & 0x3F] + output += '==' + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + (uint8[len - 1]) + output += lookup[tmp >> 10] + output += lookup[(tmp >> 4) & 0x3F] + output += lookup[(tmp << 2) & 0x3F] + output += '=' + } + + parts.push(output) + + return parts.join('') +} + +},{}],41:[function(require,module,exports){ + +},{}],42:[function(require,module,exports){ +(function (process){ +var WritableStream = require('stream').Writable +var inherits = require('util').inherits + +module.exports = BrowserStdout + + +inherits(BrowserStdout, WritableStream) + +function BrowserStdout(opts) { + if (!(this instanceof BrowserStdout)) return new BrowserStdout(opts) + + opts = opts || {} + WritableStream.call(this, opts) + this.label = (opts.label !== undefined) ? opts.label : 'stdout' +} + +BrowserStdout.prototype._write = function(chunks, encoding, cb) { + var output = chunks.toString ? chunks.toString() : chunks + if (this.label === false) { + console.log(output) + } else { + console.log(this.label+':', output) + } + process.nextTick(cb) +} + +}).call(this,require('_process')) +},{"_process":57,"stream":68,"util":73}],43:[function(require,module,exports){ +arguments[4][41][0].apply(exports,arguments) +},{"dup":41}],44:[function(require,module,exports){ +(function (global){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT */ +/* eslint-disable no-proto */ + +'use strict' var base64 = require('base64-js') var ieee754 = require('ieee754') -var isArray = require('is-array') +var isArray = require('isarray') exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer exports.INSPECT_MAX_BYTES = 50 -Buffer.poolSize = 8192 // not used by this implementation - -var rootParent = {} /** * If `Buffer.TYPED_ARRAY_SUPPORT`: @@ -6480,9 +6774,6 @@ var rootParent = {} * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. * - * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property - * on objects. - * * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. * * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of @@ -6491,20 +6782,26 @@ var rootParent = {} * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they * get the Object implementation, which is slower but behaves correctly. */ -Buffer.TYPED_ARRAY_SUPPORT = (function () { - function Bar () {} +Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined + ? global.TYPED_ARRAY_SUPPORT + : typedArraySupport() + +/* + * Export kMaxLength after typed array support is determined. + */ +exports.kMaxLength = kMaxLength() + +function typedArraySupport () { try { var arr = new Uint8Array(1) arr.foo = function () { return 42 } - arr.constructor = Bar return arr.foo() === 42 && // typed array instances can be augmented - arr.constructor === Bar && // constructor can be set typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` } catch (e) { return false } -})() +} function kMaxLength () { return Buffer.TYPED_ARRAY_SUPPORT @@ -6512,168 +6809,236 @@ function kMaxLength () { : 0x3fffffff } +function createBuffer (that, length) { + if (kMaxLength() < length) { + throw new RangeError('Invalid typed array length') + } + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = new Uint8Array(length) + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + if (that === null) { + that = new Buffer(length) + } + that.length = length + } + + return that +} + /** - * Class: Buffer - * ============= - * - * The Buffer constructor returns instances of `Uint8Array` that are augmented - * with function properties for all the node `Buffer` API functions. We use - * `Uint8Array` so that square bracket notation works as expected -- it returns - * a single octet. + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. * - * By augmenting the instances, we can avoid modifying the `Uint8Array` - * prototype. + * The `Uint8Array` prototype remains unmodified. */ -function Buffer (arg) { - if (!(this instanceof Buffer)) { - // Avoid going through an ArgumentsAdaptorTrampoline in the common case. - if (arguments.length > 1) return new Buffer(arg, arguments[1]) - return new Buffer(arg) - } - this.length = 0 - this.parent = undefined +function Buffer (arg, encodingOrOffset, length) { + if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { + return new Buffer(arg, encodingOrOffset, length) + } // Common case. if (typeof arg === 'number') { - return fromNumber(this, arg) + if (typeof encodingOrOffset === 'string') { + throw new Error( + 'If encoding is specified then the first argument must be a string' + ) + } + return allocUnsafe(this, arg) } + return from(this, arg, encodingOrOffset, length) +} - // Slightly less common case. - if (typeof arg === 'string') { - return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') - } +Buffer.poolSize = 8192 // not used by this implementation - // Unusual. - return fromObject(this, arg) +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr } -function fromNumber (that, length) { - that = allocate(that, length < 0 ? 0 : checked(length) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < length; i++) { - that[i] = 0 - } +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') } - return that -} -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } - // Assumption: byteLength() return value is always < kMaxLength. - var length = byteLength(string, encoding) | 0 - that = allocate(that, length) + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } - that.write(string, encoding) - return that + return fromObject(that, value) } -function fromObject (that, object) { - if (Buffer.isBuffer(object)) return fromBuffer(that, object) - - if (isArray(object)) return fromArray(that, object) +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(null, value, encodingOrOffset, length) +} - if (object == null) { - throw new TypeError('must start with number, buffer, array or string') +if (Buffer.TYPED_ARRAY_SUPPORT) { + Buffer.prototype.__proto__ = Uint8Array.prototype + Buffer.__proto__ = Uint8Array + if (typeof Symbol !== 'undefined' && Symbol.species && + Buffer[Symbol.species] === Buffer) { + // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true + }) } +} - if (typeof ArrayBuffer !== 'undefined') { - if (object.buffer instanceof ArrayBuffer) { - return fromTypedArray(that, object) - } - if (object instanceof ArrayBuffer) { - return fromArrayBuffer(that, object) - } +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') } +} - if (object.length) return fromArrayLike(that, object) - - return fromJsonObject(that, object) +function alloc (that, size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(that, size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(that, size).fill(fill, encoding) + : createBuffer(that, size).fill(fill) + } + return createBuffer(that, size) } -function fromBuffer (that, buffer) { - var length = checked(buffer.length) | 0 - that = allocate(that, length) - buffer.copy(that, 0, 0, length) - return that +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) } -function fromArray (that, array) { - var length = checked(array.length) | 0 - that = allocate(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 +function allocUnsafe (that, size) { + assertSize(size) + that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < size; i++) { + that[i] = 0 + } } return that } -// Duplicate of fromArray() to keep fromArray() monomorphic. -function fromTypedArray (that, array) { - var length = checked(array.length) | 0 - that = allocate(that, length) - // Truncating the elements is probably not what people expect from typed - // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior - // of the old Buffer constructor. - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(null, size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(null, size) } -function fromArrayBuffer (that, array) { - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - array.byteLength - that = Buffer._augment(new Uint8Array(array)) - } else { - // Fallback: Return an object instance of the Buffer class - that = fromTypedArray(that, new Uint8Array(array)) +function fromString (that, string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } + + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('"encoding" must be a valid string encoding') } + + var length = byteLength(string, encoding) | 0 + that = createBuffer(that, length) + + that.write(string, encoding) return that } function fromArrayLike (that, array) { var length = checked(array.length) | 0 - that = allocate(that, length) + that = createBuffer(that, length) for (var i = 0; i < length; i += 1) { that[i] = array[i] & 255 } return that } -// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. -// Returns a zero-length buffer for inputs that don't conform to the spec. -function fromJsonObject (that, object) { - var array - var length = 0 +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer - if (object.type === 'Buffer' && isArray(object.data)) { - array = object.data - length = checked(array.length) | 0 + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') } - that = allocate(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('\'length\' is out of bounds') + } + + if (length === undefined) { + array = new Uint8Array(array, byteOffset) + } else { + array = new Uint8Array(array, byteOffset, length) } - return that -} -function allocate (that, length) { if (Buffer.TYPED_ARRAY_SUPPORT) { // Return an augmented `Uint8Array` instance, for best performance - that = Buffer._augment(new Uint8Array(length)) + that = array + that.__proto__ = Buffer.prototype } else { // Fallback: Return an object instance of the Buffer class - that.length = length - that._isBuffer = true + that = fromArrayLike(that, array) + } + return that +} + +function fromObject (that, obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + that = createBuffer(that, len) + + if (that.length === 0) { + return that + } + + obj.copy(that, 0, 0, len) + return that } - var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 - if (fromPool) that.parent = rootParent + if (obj) { + if ((typeof ArrayBuffer !== 'undefined' && + obj.buffer instanceof ArrayBuffer) || 'length' in obj) { + if (typeof obj.length !== 'number' || isnan(obj.length)) { + return createBuffer(that, 0) + } + return fromArrayLike(that, obj) + } - return that + if (obj.type === 'Buffer' && isArray(obj.data)) { + return fromArrayLike(that, obj.data) + } + } + + throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') } function checked (length) { @@ -6686,12 +7051,11 @@ function checked (length) { return length | 0 } -function SlowBuffer (subject, encoding) { - if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) - - var buf = new Buffer(subject, encoding) - delete buf.parent - return buf +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 + } + return Buffer.alloc(+length) } Buffer.isBuffer = function isBuffer (b) { @@ -6708,17 +7072,12 @@ Buffer.compare = function compare (a, b) { var x = a.length var y = b.length - var i = 0 - var len = Math.min(x, y) - while (i < len) { - if (a[i] !== b[i]) break - - ++i - } - - if (i !== len) { - x = a[i] - y = b[i] + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break + } } if (x < y) return -1 @@ -6746,10 +7105,12 @@ Buffer.isEncoding = function isEncoding (encoding) { } Buffer.concat = function concat (list, length) { - if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } if (list.length === 0) { - return new Buffer(0) + return Buffer.alloc(0) } var i @@ -6760,18 +7121,30 @@ Buffer.concat = function concat (list, length) { } } - var buf = new Buffer(length) + var buffer = Buffer.allocUnsafe(length) var pos = 0 for (i = 0; i < list.length; i++) { - var item = list[i] - item.copy(buf, pos) - pos += item.length + var buf = list[i] + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length } - return buf + return buffer } function byteLength (string, encoding) { - if (typeof string !== 'string') string = '' + string + if (Buffer.isBuffer(string)) { + return string.length + } + if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' && + (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) { + return string.byteLength + } + if (typeof string !== 'string') { + string = '' + string + } var len = string.length if (len === 0) return 0 @@ -6788,6 +7161,7 @@ function byteLength (string, encoding) { return len case 'utf8': case 'utf-8': + case undefined: return utf8ToBytes(string).length case 'ucs2': case 'ucs-2': @@ -6807,20 +7181,42 @@ function byteLength (string, encoding) { } Buffer.byteLength = byteLength -// pre-set for values that may exist in the future -Buffer.prototype.length = undefined -Buffer.prototype.parent = undefined - function slowToString (encoding, start, end) { var loweredCase = false - start = start | 0 - end = end === undefined || end === Infinity ? this.length : end | 0 + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. + + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' + } + + if (end === undefined || end > this.length) { + end = this.length + } + + if (end <= 0) { + return '' + } + + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 + + if (end <= start) { + return '' + } if (!encoding) encoding = 'utf8' - if (start < 0) start = 0 - if (end > this.length) end = this.length - if (end <= start) return '' while (true) { switch (encoding) { @@ -6854,6 +7250,39 @@ function slowToString (encoding, start, end) { } } +// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect +// Buffer instances. +Buffer.prototype._isBuffer = true + +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i +} + +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') + } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) + } + return this +} + +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) + } + return this +} + Buffer.prototype.toString = function toString () { var length = this.length | 0 if (length === 0) return '' @@ -6877,15 +7306,114 @@ Buffer.prototype.inspect = function inspect () { return '' } -Buffer.prototype.compare = function compare (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return 0 - return Buffer.compare(this, b) +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (!Buffer.isBuffer(target)) { + throw new TypeError('Argument must be a Buffer') + } + + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length + } + + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } + + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 + } + + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 + + if (this === target) return 0 + + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) + + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break + } + } + + if (x < y) return -1 + if (y < x) return 1 + return 0 +} + +function arrayIndexOf (arr, val, byteOffset, encoding) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length + + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 + } + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 + } + } + + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) + } + } + + var foundIndex = -1 + for (var i = 0; byteOffset + i < arrLength; i++) { + if (read(arr, byteOffset + i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return (byteOffset + foundIndex) * indexSize + } else { + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 + } + } + return -1 } -Buffer.prototype.indexOf = function indexOf (val, byteOffset) { - if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff - else if (byteOffset < -0x80000000) byteOffset = -0x80000000 +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } byteOffset >>= 0 if (this.length === 0) return -1 @@ -6895,45 +7423,28 @@ Buffer.prototype.indexOf = function indexOf (val, byteOffset) { if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) if (typeof val === 'string') { - if (val.length === 0) return -1 // special case: looking for empty string always fails - return String.prototype.indexOf.call(this, val, byteOffset) + val = Buffer.from(val, encoding) } + if (Buffer.isBuffer(val)) { - return arrayIndexOf(this, val, byteOffset) + // special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(this, val, byteOffset, encoding) } if (typeof val === 'number') { if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { return Uint8Array.prototype.indexOf.call(this, val, byteOffset) } - return arrayIndexOf(this, [ val ], byteOffset) - } - - function arrayIndexOf (arr, val, byteOffset) { - var foundIndex = -1 - for (var i = 0; byteOffset + i < arr.length; i++) { - if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex - } else { - foundIndex = -1 - } - } - return -1 + return arrayIndexOf(this, [ val ], byteOffset, encoding) } throw new TypeError('val must be string, number or Buffer') } -// `get` is deprecated -Buffer.prototype.get = function get (offset) { - console.log('.get() is deprecated. Access using array indexes instead.') - return this.readUInt8(offset) -} - -// `set` is deprecated -Buffer.prototype.set = function set (v, offset) { - console.log('.set() is deprecated. Access using array indexes instead.') - return this.writeUInt8(v, offset) +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 } function hexWrite (buf, string, offset, length) { @@ -6957,7 +7468,7 @@ function hexWrite (buf, string, offset, length) { } for (var i = 0; i < length; i++) { var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) throw new Error('Invalid hex string') + if (isNaN(parsed)) return i buf[offset + i] = parsed } return i @@ -7006,17 +7517,16 @@ Buffer.prototype.write = function write (string, offset, length, encoding) { } // legacy write(string, encoding, offset, length) - remove in v0.13 } else { - var swap = encoding - encoding = offset - offset = length | 0 - length = swap + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) } var remaining = this.length - offset if (length === undefined || length > remaining) length = remaining if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('attempt to write outside buffer bounds') + throw new RangeError('Attempt to write outside buffer bounds') } if (!encoding) encoding = 'utf8' @@ -7231,7 +7741,8 @@ Buffer.prototype.slice = function slice (start, end) { var newBuf if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = Buffer._augment(this.subarray(start, end)) + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype } else { var sliceLen = end - start newBuf = new Buffer(sliceLen, undefined) @@ -7240,8 +7751,6 @@ Buffer.prototype.slice = function slice (start, end) { } } - if (newBuf.length) newBuf.parent = this.parent || this - return newBuf } @@ -7410,16 +7919,19 @@ Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { } function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') - if (value > max || value < min) throw new RangeError('value is out of bounds') - if (offset + ext > buf.length) throw new RangeError('index out of range') + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') } Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 - if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } var mul = 1 var i = 0 @@ -7435,7 +7947,10 @@ Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, value = +value offset = offset | 0 byteLength = byteLength | 0 - if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } var i = byteLength - 1 var mul = 1 @@ -7452,7 +7967,7 @@ Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = value + this[offset] = (value & 0xff) return offset + 1 } @@ -7469,7 +7984,7 @@ Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = value + this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) } else { objectWriteUInt16(this, value, offset, true) @@ -7483,7 +7998,7 @@ Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) - this[offset + 1] = value + this[offset + 1] = (value & 0xff) } else { objectWriteUInt16(this, value, offset, false) } @@ -7505,7 +8020,7 @@ Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert this[offset + 3] = (value >>> 24) this[offset + 2] = (value >>> 16) this[offset + 1] = (value >>> 8) - this[offset] = value + this[offset] = (value & 0xff) } else { objectWriteUInt32(this, value, offset, true) } @@ -7520,7 +8035,7 @@ Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) - this[offset + 3] = value + this[offset + 3] = (value & 0xff) } else { objectWriteUInt32(this, value, offset, false) } @@ -7538,9 +8053,12 @@ Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, no var i = 0 var mul = 1 - var sub = value < 0 ? 1 : 0 + var sub = 0 this[offset] = value & 0xFF while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 + } this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } @@ -7558,9 +8076,12 @@ Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, no var i = byteLength - 1 var mul = 1 - var sub = value < 0 ? 1 : 0 + var sub = 0 this[offset + i] = value & 0xFF while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 + } this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } @@ -7573,7 +8094,7 @@ Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) if (value < 0) value = 0xff + value + 1 - this[offset] = value + this[offset] = (value & 0xff) return offset + 1 } @@ -7582,7 +8103,7 @@ Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = value + this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) } else { objectWriteUInt16(this, value, offset, true) @@ -7596,7 +8117,7 @@ Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) if (Buffer.TYPED_ARRAY_SUPPORT) { this[offset] = (value >>> 8) - this[offset + 1] = value + this[offset + 1] = (value & 0xff) } else { objectWriteUInt16(this, value, offset, false) } @@ -7608,7 +8129,7 @@ Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = value + this[offset] = (value & 0xff) this[offset + 1] = (value >>> 8) this[offset + 2] = (value >>> 16) this[offset + 3] = (value >>> 24) @@ -7627,7 +8148,7 @@ Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) this[offset] = (value >>> 24) this[offset + 1] = (value >>> 16) this[offset + 2] = (value >>> 8) - this[offset + 3] = value + this[offset + 3] = (value & 0xff) } else { objectWriteUInt32(this, value, offset, false) } @@ -7635,9 +8156,8 @@ Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) } function checkIEEE754 (buf, value, offset, ext, max, min) { - if (value > max || value < min) throw new RangeError('value is out of bounds') - if (offset + ext > buf.length) throw new RangeError('index out of range') - if (offset < 0) throw new RangeError('index out of range') + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') } function writeFloat (buf, value, offset, littleEndian, noAssert) { @@ -7711,134 +8231,82 @@ Buffer.prototype.copy = function copy (target, targetStart, start, end) { target[i + targetStart] = this[i + start] } } else { - target._set(this.subarray(start, start + len), targetStart) + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) } return len } -// fill(value, start=0, end=buffer.length) -Buffer.prototype.fill = function fill (value, start, end) { - if (!value) value = 0 - if (!start) start = 0 - if (!end) end = this.length +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if (code < 256) { + val = code + } + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + } else if (typeof val === 'number') { + val = val & 255 + } + + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } - if (end < start) throw new RangeError('end < start') + if (end <= start) { + return this + } - // Fill 0 bytes; we're done - if (end === start) return - if (this.length === 0) return + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 - if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') - if (end < 0 || end > this.length) throw new RangeError('end out of bounds') + if (!val) val = 0 var i - if (typeof value === 'number') { + if (typeof val === 'number') { for (i = start; i < end; i++) { - this[i] = value + this[i] = val } } else { - var bytes = utf8ToBytes(value.toString()) + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) var len = bytes.length - for (i = start; i < end; i++) { - this[i] = bytes[i % len] + for (i = 0; i < end - start; i++) { + this[i + start] = bytes[i % len] } } return this } -/** - * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. - * Added in Node 0.12. Only available in browsers that support ArrayBuffer. - */ -Buffer.prototype.toArrayBuffer = function toArrayBuffer () { - if (typeof Uint8Array !== 'undefined') { - if (Buffer.TYPED_ARRAY_SUPPORT) { - return (new Buffer(this)).buffer - } else { - var buf = new Uint8Array(this.length) - for (var i = 0, len = buf.length; i < len; i += 1) { - buf[i] = this[i] - } - return buf.buffer - } - } else { - throw new TypeError('Buffer.toArrayBuffer not supported in this browser') - } -} - // HELPER FUNCTIONS // ================ -var BP = Buffer.prototype - -/** - * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods - */ -Buffer._augment = function _augment (arr) { - arr.constructor = Buffer - arr._isBuffer = true - - // save reference to original Uint8Array set method before overwriting - arr._set = arr.set - - // deprecated - arr.get = BP.get - arr.set = BP.set - - arr.write = BP.write - arr.toString = BP.toString - arr.toLocaleString = BP.toString - arr.toJSON = BP.toJSON - arr.equals = BP.equals - arr.compare = BP.compare - arr.indexOf = BP.indexOf - arr.copy = BP.copy - arr.slice = BP.slice - arr.readUIntLE = BP.readUIntLE - arr.readUIntBE = BP.readUIntBE - arr.readUInt8 = BP.readUInt8 - arr.readUInt16LE = BP.readUInt16LE - arr.readUInt16BE = BP.readUInt16BE - arr.readUInt32LE = BP.readUInt32LE - arr.readUInt32BE = BP.readUInt32BE - arr.readIntLE = BP.readIntLE - arr.readIntBE = BP.readIntBE - arr.readInt8 = BP.readInt8 - arr.readInt16LE = BP.readInt16LE - arr.readInt16BE = BP.readInt16BE - arr.readInt32LE = BP.readInt32LE - arr.readInt32BE = BP.readInt32BE - arr.readFloatLE = BP.readFloatLE - arr.readFloatBE = BP.readFloatBE - arr.readDoubleLE = BP.readDoubleLE - arr.readDoubleBE = BP.readDoubleBE - arr.writeUInt8 = BP.writeUInt8 - arr.writeUIntLE = BP.writeUIntLE - arr.writeUIntBE = BP.writeUIntBE - arr.writeUInt16LE = BP.writeUInt16LE - arr.writeUInt16BE = BP.writeUInt16BE - arr.writeUInt32LE = BP.writeUInt32LE - arr.writeUInt32BE = BP.writeUInt32BE - arr.writeIntLE = BP.writeIntLE - arr.writeIntBE = BP.writeIntBE - arr.writeInt8 = BP.writeInt8 - arr.writeInt16LE = BP.writeInt16LE - arr.writeInt16BE = BP.writeInt16BE - arr.writeInt32LE = BP.writeInt32LE - arr.writeInt32BE = BP.writeInt32BE - arr.writeFloatLE = BP.writeFloatLE - arr.writeFloatBE = BP.writeFloatBE - arr.writeDoubleLE = BP.writeDoubleLE - arr.writeDoubleBE = BP.writeDoubleBE - arr.fill = BP.fill - arr.inspect = BP.inspect - arr.toArrayBuffer = BP.toArrayBuffer - - return arr -} - var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g function base64clean (str) { @@ -7902,7 +8370,7 @@ function utf8ToBytes (string, units) { } // valid surrogate pair - codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 } else if (leadSurrogate) { // valid bmp char, but last char was a lead if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) @@ -7980,254 +8448,13 @@ function blitBuffer (src, dst, offset, length) { return i } -},{"base64-js":44,"ieee754":45,"is-array":46}],44:[function(require,module,exports){ -var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -;(function (exports) { - 'use strict'; - - var Arr = (typeof Uint8Array !== 'undefined') - ? Uint8Array - : Array - - var PLUS = '+'.charCodeAt(0) - var SLASH = '/'.charCodeAt(0) - var NUMBER = '0'.charCodeAt(0) - var LOWER = 'a'.charCodeAt(0) - var UPPER = 'A'.charCodeAt(0) - var PLUS_URL_SAFE = '-'.charCodeAt(0) - var SLASH_URL_SAFE = '_'.charCodeAt(0) - - function decode (elt) { - var code = elt.charCodeAt(0) - if (code === PLUS || - code === PLUS_URL_SAFE) - return 62 // '+' - if (code === SLASH || - code === SLASH_URL_SAFE) - return 63 // '/' - if (code < NUMBER) - return -1 //no match - if (code < NUMBER + 10) - return code - NUMBER + 26 + 26 - if (code < UPPER + 26) - return code - UPPER - if (code < LOWER + 26) - return code - LOWER + 26 - } - - function b64ToByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - - if (b64.length % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - var len = b64.length - placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(b64.length * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length - - var L = 0 - - function push (v) { - arr[L++] = v - } - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) - push((tmp & 0xFF0000) >> 16) - push((tmp & 0xFF00) >> 8) - push(tmp & 0xFF) - } - - if (placeHolders === 2) { - tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) - push(tmp & 0xFF) - } else if (placeHolders === 1) { - tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) - push((tmp >> 8) & 0xFF) - push(tmp & 0xFF) - } - - return arr - } - - function uint8ToBase64 (uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length - - function encode (num) { - return lookup.charAt(num) - } - - function tripletToBase64 (num) { - return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) - } - - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output += tripletToBase64(temp) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1] - output += encode(temp >> 2) - output += encode((temp << 4) & 0x3F) - output += '==' - break - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) - output += encode(temp >> 10) - output += encode((temp >> 4) & 0x3F) - output += encode((temp << 2) & 0x3F) - output += '=' - break - } - - return output - } - - exports.toByteArray = b64ToByteArray - exports.fromByteArray = uint8ToBase64 -}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) - -},{}],45:[function(require,module,exports){ -exports.read = function (buffer, offset, isLE, mLen, nBytes) { - var e, m - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var nBits = -7 - var i = isLE ? (nBytes - 1) : 0 - var d = isLE ? -1 : 1 - var s = buffer[offset + i] - - i += d - - e = s & ((1 << (-nBits)) - 1) - s >>= (-nBits) - nBits += eLen - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - m = e & ((1 << (-nBits)) - 1) - e >>= (-nBits) - nBits += mLen - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} - - if (e === 0) { - e = 1 - eBias - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity) - } else { - m = m + Math.pow(2, mLen) - e = e - eBias - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen) -} - -exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c - var eLen = nBytes * 8 - mLen - 1 - var eMax = (1 << eLen) - 1 - var eBias = eMax >> 1 - var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) - var i = isLE ? 0 : (nBytes - 1) - var d = isLE ? 1 : -1 - var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - - value = Math.abs(value) - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0 - e = eMax - } else { - e = Math.floor(Math.log(value) / Math.LN2) - if (value * (c = Math.pow(2, -e)) < 1) { - e-- - c *= 2 - } - if (e + eBias >= 1) { - value += rt / c - } else { - value += rt * Math.pow(2, 1 - eBias) - } - if (value * c >= 2) { - e++ - c /= 2 - } - - if (e + eBias >= eMax) { - m = 0 - e = eMax - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen) - e = e + eBias - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) - e = 0 - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} - - e = (e << mLen) | m - eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} - - buffer[offset + i - d] |= s * 128 +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare } -},{}],46:[function(require,module,exports){ - -/** - * isArray - */ - -var isArray = Array.isArray; - -/** - * toString - */ - -var str = Object.prototype.toString; - -/** - * Whether or not the given `val` - * is an array. - * - * example: - * - * isArray([]); - * // > true - * isArray(arguments); - * // > false - * isArray(''); - * // > false - * - * @param {mixed} val - * @return {bool} - */ - -module.exports = isArray || function (val) { - return !! val && '[object Array]' == str.call(val); -}; - -},{}],47:[function(require,module,exports){ +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"base64-js":40,"ieee754":50,"isarray":53}],45:[function(require,module,exports){ +(function (Buffer){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -8249,603 +8476,729 @@ module.exports = isArray || function (val) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -function EventEmitter() { - this._events = this._events || {}; - this._maxListeners = this._maxListeners || undefined; -} -module.exports = EventEmitter; +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._maxListeners = undefined; +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); - this._maxListeners = n; - return this; -}; +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; - if (!this._events) - this._events = {}; +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; - // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { - er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); - } - } +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; - handler = this._events[type]; +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; - if (isUndefined(handler)) - return false; +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; - if (isFunction(handler)) { - switch (arguments.length) { - // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; - // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); - } +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - return true; -}; +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; -EventEmitter.prototype.addListener = function(type, listener) { - var m; +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; - if (!this._events) - this._events = {}; +exports.isBuffer = Buffer.isBuffer; - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); +function objectToString(o) { + return Object.prototype.toString.call(o); +} - if (!this._events[type]) - // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; +}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) +},{"../../is-buffer/index.js":52}],46:[function(require,module,exports){ +/* See LICENSE file for terms of use */ - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; - } else { - m = EventEmitter.defaultMaxListeners; +/* + * Text diff implementation. + * + * This library supports the following APIS: + * JsDiff.diffChars: Character by character diff + * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace + * JsDiff.diffLines: Line based diff + * + * JsDiff.diffCss: Diff targeted at CSS content + * + * These methods are based on the implementation proposed in + * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 + */ +(function(global, undefined) { + var objectPrototypeToString = Object.prototype.toString; + + /*istanbul ignore next*/ + function map(arr, mapper, that) { + if (Array.prototype.map) { + return Array.prototype.map.call(arr, mapper, that); } - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); + var other = new Array(arr.length); + + for (var i = 0, n = arr.length; i < n; i++) { + other[i] = mapper.call(that, arr[i], i, arr); + } + return other; + } + function clonePath(path) { + return { newPos: path.newPos, components: path.components.slice(0) }; + } + function removeEmpty(array) { + var ret = []; + for (var i = 0; i < array.length; i++) { + if (array[i]) { + ret.push(array[i]); } } + return ret; } + function escapeHTML(s) { + var n = s; + n = n.replace(/&/g, '&'); + n = n.replace(//g, '>'); + n = n.replace(/"/g, '"'); - return this; -}; + return n; + } -EventEmitter.prototype.on = EventEmitter.prototype.addListener; + // This function handles the presence of circular references by bailing out when encountering an + // object that is already on the "stack" of items being processed. + function canonicalize(obj, stack, replacementStack) { + stack = stack || []; + replacementStack = replacementStack || []; -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); + var i; - var fired = false; + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } - function g() { - this.removeListener(type, g); + var canonicalizedObj; - if (!fired) { - fired = true; - listener.apply(this, arguments); + if ('[object Array]' === objectPrototypeToString.call(obj)) { + stack.push(obj); + canonicalizedObj = new Array(obj.length); + replacementStack.push(canonicalizedObj); + for (i = 0; i < obj.length; i += 1) { + canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); + } + stack.pop(); + replacementStack.pop(); + } else if (typeof obj === 'object' && obj !== null) { + stack.push(obj); + canonicalizedObj = {}; + replacementStack.push(canonicalizedObj); + var sortedKeys = [], + key; + for (key in obj) { + sortedKeys.push(key); + } + sortedKeys.sort(); + for (i = 0; i < sortedKeys.length; i += 1) { + key = sortedKeys[i]; + canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); + } + stack.pop(); + replacementStack.pop(); + } else { + canonicalizedObj = obj; } + return canonicalizedObj; } - g.listener = listener; - this.on(type, g); - - return this; -}; - -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; - - if (!isFunction(listener)) - throw TypeError('listener must be a function'); + function buildValues(components, newString, oldString, useLongestToken) { + var componentPos = 0, + componentLen = components.length, + newPos = 0, + oldPos = 0; - if (!this._events || !this._events[type]) - return this; + for (; componentPos < componentLen; componentPos++) { + var component = components[componentPos]; + if (!component.removed) { + if (!component.added && useLongestToken) { + var value = newString.slice(newPos, newPos + component.count); + value = map(value, function(value, i) { + var oldValue = oldString[oldPos + i]; + return oldValue.length > value.length ? oldValue : value; + }); - list = this._events[type]; - length = list.length; - position = -1; + component.value = value.join(''); + } else { + component.value = newString.slice(newPos, newPos + component.count).join(''); + } + newPos += component.count; - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); + // Common case + if (!component.added) { + oldPos += component.count; + } + } else { + component.value = oldString.slice(oldPos, oldPos + component.count).join(''); + oldPos += component.count; - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; + // Reverse add and remove so removes are output first to match common convention + // The diffing algorithm is tied to add then remove output and this is the simplest + // route to get the desired output with minimal overhead. + if (componentPos && components[componentPos - 1].added) { + var tmp = components[componentPos - 1]; + components[componentPos - 1] = components[componentPos]; + components[componentPos] = tmp; + } } } - if (position < 0) - return this; - - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } + return components; + } - if (this._events.removeListener) - this.emit('removeListener', type, listener); + function Diff(ignoreWhitespace) { + this.ignoreWhitespace = ignoreWhitespace; } + Diff.prototype = { + diff: function(oldString, newString, callback) { + var self = this; - return this; -}; + function done(value) { + if (callback) { + setTimeout(function() { callback(undefined, value); }, 0); + return true; + } else { + return value; + } + } -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; + // Handle the identity case (this is due to unrolling editLength == 0 + if (newString === oldString) { + return done([{ value: newString }]); + } + if (!newString) { + return done([{ value: oldString, removed: true }]); + } + if (!oldString) { + return done([{ value: newString, added: true }]); + } - if (!this._events) - return this; + newString = this.tokenize(newString); + oldString = this.tokenize(oldString); - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } + var newLen = newString.length, oldLen = oldString.length; + var editLength = 1; + var maxEditLength = newLen + oldLen; + var bestPath = [{ newPos: -1, components: [] }]; - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } + // Seed editLength = 0, i.e. the content starts with the same values + var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); + if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + // Identity per the equality and tokenizer + return done([{value: newString.join('')}]); + } - listeners = this._events[type]; + // Main worker method. checks all permutations of a given edit length for acceptance. + function execEditLength() { + for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { + var basePath; + var addPath = bestPath[diagonalPath - 1], + removePath = bestPath[diagonalPath + 1], + oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; + if (addPath) { + // No one else is going to attempt to use this value, clear it + bestPath[diagonalPath - 1] = undefined; + } - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; + var canAdd = addPath && addPath.newPos + 1 < newLen, + canRemove = removePath && 0 <= oldPos && oldPos < oldLen; + if (!canAdd && !canRemove) { + // If this path is a terminal then prune + bestPath[diagonalPath] = undefined; + continue; + } - return this; -}; + // Select the diagonal that we want to branch from. We select the prior + // path whose position in the new string is the farthest from the origin + // and does not pass the bounds of the diff graph + if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) { + basePath = clonePath(removePath); + self.pushComponent(basePath.components, undefined, true); + } else { + basePath = addPath; // No need to clone, we've pulled it from the list + basePath.newPos++; + self.pushComponent(basePath.components, true, undefined); + } -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; -}; + oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); -EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; -}; + // If we have hit the end of both strings, then we are done + if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) { + return done(buildValues(basePath.components, newString, oldString, self.useLongestToken)); + } else { + // Otherwise track this path as a potential candidate and continue. + bestPath[diagonalPath] = basePath; + } + } -function isFunction(arg) { - return typeof arg === 'function'; -} + editLength++; + } -function isNumber(arg) { - return typeof arg === 'number'; -} + // Performs the length of edit iteration. Is a bit fugly as this has to support the + // sync and async mode which is never fun. Loops over execEditLength until a value + // is produced. + if (callback) { + (function exec() { + setTimeout(function() { + // This should not happen, but we want to be safe. + /*istanbul ignore next */ + if (editLength > maxEditLength) { + return callback(); + } -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} + if (!execEditLength()) { + exec(); + } + }, 0); + }()); + } else { + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } + } + }, -function isUndefined(arg) { - return arg === void 0; -} + pushComponent: function(components, added, removed) { + var last = components[components.length - 1]; + if (last && last.added === added && last.removed === removed) { + // We need to clone here as the component clone operation is just + // as shallow array clone + components[components.length - 1] = {count: last.count + 1, added: added, removed: removed }; + } else { + components.push({count: 1, added: added, removed: removed }); + } + }, + extractCommon: function(basePath, newString, oldString, diagonalPath) { + var newLen = newString.length, + oldLen = oldString.length, + newPos = basePath.newPos, + oldPos = newPos - diagonalPath, -},{}],48:[function(require,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true + commonCount = 0; + while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { + newPos++; + oldPos++; + commonCount++; } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} -},{}],49:[function(require,module,exports){ -module.exports = Array.isArray || function (arr) { - return Object.prototype.toString.call(arr) == '[object Array]'; -}; + if (commonCount) { + basePath.components.push({count: commonCount}); + } -},{}],50:[function(require,module,exports){ -exports.endianness = function () { return 'LE' }; + basePath.newPos = newPos; + return oldPos; + }, -exports.hostname = function () { - if (typeof location !== 'undefined') { - return location.hostname + equals: function(left, right) { + var reWhitespace = /\S/; + return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)); + }, + tokenize: function(value) { + return value.split(''); } - else return ''; -}; + }; -exports.loadavg = function () { return [] }; + var CharDiff = new Diff(); -exports.uptime = function () { return 0 }; + var WordDiff = new Diff(true); + var WordWithSpaceDiff = new Diff(); + WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\s+|\b)/)); + }; -exports.freemem = function () { - return Number.MAX_VALUE; -}; + var CssDiff = new Diff(true); + CssDiff.tokenize = function(value) { + return removeEmpty(value.split(/([{}:;,]|\s+)/)); + }; -exports.totalmem = function () { - return Number.MAX_VALUE; -}; + var LineDiff = new Diff(); -exports.cpus = function () { return [] }; + var TrimmedLineDiff = new Diff(); + TrimmedLineDiff.ignoreTrim = true; -exports.type = function () { return 'Browser' }; + LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) { + var retLines = [], + lines = value.split(/^/m); + for (var i = 0; i < lines.length; i++) { + var line = lines[i], + lastLine = lines[i - 1], + lastLineLastChar = lastLine && lastLine[lastLine.length - 1]; -exports.release = function () { - if (typeof navigator !== 'undefined') { - return navigator.appVersion; + // Merge lines that may contain windows new lines + if (line === '\n' && lastLineLastChar === '\r') { + retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\r\n'; + } else { + if (this.ignoreTrim) { + line = line.trim(); + // add a newline unless this is the last line. + if (i < lines.length - 1) { + line += '\n'; + } + } + retLines.push(line); + } } - return ''; -}; - -exports.networkInterfaces -= exports.getNetworkInterfaces -= function () { return {} }; -exports.arch = function () { return 'javascript' }; + return retLines; + }; -exports.platform = function () { return 'browser' }; + var PatchDiff = new Diff(); + PatchDiff.tokenize = function(value) { + var ret = [], + linesAndNewlines = value.split(/(\n|\r\n)/); -exports.tmpdir = exports.tmpDir = function () { - return '/tmp'; -}; - -exports.EOL = '\n'; - -},{}],51:[function(require,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); } - var timeout = setTimeout(cleanUpNextTick); - draining = true; - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - clearTimeout(timeout); -} + // Merge the content and line separators into single tokens + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - setTimeout(drainQueue, 0); + if (i % 2) { + ret[ret.length - 1] += line; + } else { + ret.push(line); + } } -}; + return ret; + }; -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; + var SentenceDiff = new Diff(); + SentenceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/)); + }; -function noop() {} + var JsonDiff = new Diff(); + // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a + // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: + JsonDiff.useLongestToken = true; + JsonDiff.tokenize = LineDiff.tokenize; + JsonDiff.equals = function(left, right) { + return LineDiff.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); + }; -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; + var JsDiff = { + Diff: Diff, -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; + diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); }, + diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); }, + diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); }, + diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); }, + diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); }, -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; + diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); }, -},{}],52:[function(require,module,exports){ -module.exports = require("./lib/_stream_duplex.js") + diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); }, + diffJson: function(oldObj, newObj, callback) { + return JsonDiff.diff( + typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, ' '), + typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, ' '), + callback + ); + }, -},{"./lib/_stream_duplex.js":53}],53:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) { + var ret = []; -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. + if (oldFileName == newFileName) { + ret.push('Index: ' + oldFileName); + } + ret.push('==================================================================='); + ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader)); + ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader)); -module.exports = Duplex; + var diff = PatchDiff.diff(oldStr, newStr); + diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier -/**/ -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) keys.push(key); - return keys; -} -/**/ + // Formats a given set of lines for printing as context lines in a patch + function contextLines(lines) { + return map(lines, function(entry) { return ' ' + entry; }); + } + // Outputs the no newline at end of file warning if needed + function eofNL(curRange, i, current) { + var last = diff[diff.length - 2], + isLast = i === diff.length - 2, + isLastOfType = i === diff.length - 3 && current.added !== last.added; -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ + // Figure out if this is the last line for the given file and missing NL + if (!(/\n$/.test(current.value)) && (isLast || isLastOfType)) { + curRange.push('\\ No newline at end of file'); + } + } -var Readable = require('./_stream_readable'); -var Writable = require('./_stream_writable'); + var oldRangeStart = 0, newRangeStart = 0, curRange = [], + oldLine = 1, newLine = 1; + for (var i = 0; i < diff.length; i++) { + var current = diff[i], + lines = current.lines || current.value.replace(/\n$/, '').split('\n'); + current.lines = lines; -util.inherits(Duplex, Readable); + if (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + var prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; -forEach(objectKeys(Writable.prototype), function(method) { - if (!Duplex.prototype[method]) - Duplex.prototype[method] = Writable.prototype[method]; -}); + if (prev) { + curRange = contextLines(prev.lines.slice(-4)); + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } -function Duplex(options) { - if (!(this instanceof Duplex)) - return new Duplex(options); + // Output our changes + curRange.push.apply(curRange, map(lines, function(entry) { + return (current.added ? '+' : '-') + entry; + })); + eofNL(curRange, i, current); - Readable.call(this, options); - Writable.call(this, options); + // Track the updated file position + if (current.added) { + newLine += lines.length; + } else { + oldLine += lines.length; + } + } else { + // Identical context lines. Track line changes + if (oldRangeStart) { + // Close out any changes that have been output (or join overlapping) + if (lines.length <= 8 && i < diff.length - 2) { + // Overlapping + curRange.push.apply(curRange, contextLines(lines)); + } else { + // end the range and output + var contextSize = Math.min(lines.length, 4); + ret.push( + '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) + + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) + + ' @@'); + ret.push.apply(ret, curRange); + ret.push.apply(ret, contextLines(lines.slice(0, contextSize))); + if (lines.length <= 4) { + eofNL(ret, i, current); + } - if (options && options.readable === false) - this.readable = false; + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } - if (options && options.writable === false) - this.writable = false; + return ret.join('\n') + '\n'; + }, - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) - this.allowHalfOpen = false; + createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) { + return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader); + }, - this.once('end', onend); -} + applyPatch: function(oldStr, uniDiff) { + var diffstr = uniDiff.split('\n'), + hunks = [], + i = 0, + remEOFNL = false, + addEOFNL = false; -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) - return; + // Skip to the first change hunk + while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) { + i++; + } - // no more data can be written. - // But allow more writes to happen in this tick. - process.nextTick(this.end.bind(this)); -} + // Parse the unified diff + for (; i < diffstr.length; i++) { + if (diffstr[i][0] === '@') { + var chnukHeader = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/); + hunks.unshift({ + start: chnukHeader[3], + oldlength: +chnukHeader[2], + removed: [], + newlength: chnukHeader[4], + added: [] + }); + } else if (diffstr[i][0] === '+') { + hunks[0].added.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === '-') { + hunks[0].removed.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === ' ') { + hunks[0].added.push(diffstr[i].substr(1)); + hunks[0].removed.push(diffstr[i].substr(1)); + } else if (diffstr[i][0] === '\\') { + if (diffstr[i - 1][0] === '+') { + remEOFNL = true; + } else if (diffstr[i - 1][0] === '-') { + addEOFNL = true; + } + } + } -function forEach (xs, f) { - for (var i = 0, l = xs.length; i < l; i++) { - f(xs[i], i); - } -} + // Apply the diff to the input + var lines = oldStr.split('\n'); + for (i = hunks.length - 1; i >= 0; i--) { + var hunk = hunks[i]; + // Sanity check the input string. Bail if we don't match. + for (var j = 0; j < hunk.oldlength; j++) { + if (lines[hunk.start - 1 + j] !== hunk.removed[j]) { + return false; + } + } + Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added)); + } -}).call(this,require('_process')) -},{"./_stream_readable":55,"./_stream_writable":57,"_process":51,"core-util-is":58,"inherits":48}],54:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + // Handle EOFNL insertion/removal + if (remEOFNL) { + while (!lines[lines.length - 1]) { + lines.pop(); + } + } else if (addEOFNL) { + lines.push(''); + } + return lines.join('\n'); + }, -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. + convertChangesToXML: function(changes) { + var ret = []; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } -module.exports = PassThrough; + ret.push(escapeHTML(change.value)); -var Transform = require('./_stream_transform'); + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } + } + return ret.join(''); + }, -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ + // See: http://code.google.com/p/google-diff-match-patch/wiki/API + convertChangesToDMP: function(changes) { + var ret = [], + change, + operation; + for (var i = 0; i < changes.length; i++) { + change = changes[i]; + if (change.added) { + operation = 1; + } else if (change.removed) { + operation = -1; + } else { + operation = 0; + } -util.inherits(PassThrough, Transform); + ret.push([operation, change.value]); + } + return ret; + }, -function PassThrough(options) { - if (!(this instanceof PassThrough)) - return new PassThrough(options); + canonicalize: canonicalize + }; - Transform.call(this, options); -} + /*istanbul ignore next */ + /*global module */ + if (typeof module !== 'undefined' && module.exports) { + module.exports = JsDiff; + } else if (typeof define === 'function' && define.amd) { + /*global define */ + define([], function() { return JsDiff; }); + } else if (typeof global.JsDiff === 'undefined') { + global.JsDiff = JsDiff; + } +}(this)); -PassThrough.prototype._transform = function(chunk, encoding, cb) { - cb(null, chunk); +},{}],47:[function(require,module,exports){ +'use strict'; + +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + +module.exports = function (str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + + return str.replace(matchOperatorsRe, '\\$&'); }; -},{"./_stream_transform":56,"core-util-is":58,"inherits":48}],55:[function(require,module,exports){ -(function (process){ +},{}],48:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -8867,3844 +9220,3784 @@ PassThrough.prototype._transform = function(chunk, encoding, cb) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -module.exports = Readable; - -/**/ -var isArray = require('isarray'); -/**/ - +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; -/**/ -var Buffer = require('buffer').Buffer; -/**/ +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; -Readable.ReadableState = ReadableState; +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; -var EE = require('events').EventEmitter; +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; -/**/ -if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { - return emitter.listeners(type).length; +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; }; -/**/ -var Stream = require('stream'); +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; -/**/ -var util = require('core-util-is'); -util.inherits = require('inherits'); -/**/ + if (!this._events) + this._events = {}; -var StringDecoder; + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } + throw TypeError('Uncaught, unspecified "error" event.'); + } + } + handler = this._events[type]; -/**/ -var debug = require('util'); -if (debug && debug.debuglog) { - debug = debug.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ + if (isUndefined(handler)) + return false; + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + args = Array.prototype.slice.call(arguments, 1); + handler.apply(this, args); + } + } else if (isObject(handler)) { + args = Array.prototype.slice.call(arguments, 1); + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } -util.inherits(Readable, Stream); + return true; +}; -function ReadableState(options, stream) { - var Duplex = require('./_stream_duplex'); +EventEmitter.prototype.addListener = function(type, listener) { + var m; - options = options || {}; + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var defaultHwm = options.objectMode ? 16 : 16 * 1024; - this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + if (!this._events) + this._events = {}; - // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); - this.buffer = []; - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + return this; +}; - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; +EventEmitter.prototype.on = EventEmitter.prototype.addListener; - if (stream instanceof Duplex) - this.objectMode = this.objectMode || !!options.readableObjectMode; +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; + var fired = false; - // when piping, we only care about 'readable' events that happen - // after read()ing all the bytes and not getting any pushback. - this.ranOut = false; + function g() { + this.removeListener(type, g); - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } - // if true, a maybeReadMore has been scheduled - this.readingMore = false; + g.listener = listener; + this.on(type, g); - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) - StringDecoder = require('string_decoder/').StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} + return this; +}; -function Readable(options) { - var Duplex = require('./_stream_duplex'); +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; - if (!(this instanceof Readable)) - return new Readable(options); + if (!isFunction(listener)) + throw TypeError('listener must be a function'); - this._readableState = new ReadableState(options, this); + if (!this._events || !this._events[type]) + return this; - // legacy - this.readable = true; + list = this._events[type]; + length = list.length; + position = -1; - Stream.call(this); -} + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function(chunk, encoding) { - var state = this._readableState; + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } - if (util.isString(chunk) && !state.objectMode) { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = new Buffer(chunk, encoding); - encoding = ''; + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); } - } - return readableAddChunk(this, state, chunk, encoding, false); -}; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function(chunk) { - var state = this._readableState; - return readableAddChunk(this, state, chunk, '', true); + return this; }; -function readableAddChunk(stream, state, chunk, encoding, addToFront) { - var er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (util.isNullOrUndefined(chunk)) { - state.reading = false; - if (!state.ended) - onEofChunk(stream, state); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (state.ended && !addToFront) { - var e = new Error('stream.push() after EOF'); - stream.emit('error', e); - } else if (state.endEmitted && addToFront) { - var e = new Error('stream.unshift() after end event'); - stream.emit('error', e); - } else { - if (state.decoder && !addToFront && !encoding) - chunk = state.decoder.write(chunk); +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; - if (!addToFront) - state.reading = false; + if (!this._events) + return this; - // if we want the data now, just emit it. - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) - state.buffer.unshift(chunk); - else - state.buffer.push(chunk); - - if (state.needReadable) - emitReadable(stream); - } + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } - maybeReadMore(stream, state); + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); } - } else if (!addToFront) { - state.reading = false; + this.removeAllListeners('removeListener'); + this._events = {}; + return this; } - return needMoreData(state); -} - - + listeners = this._events[type]; -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && - (state.needReadable || - state.length < state.highWaterMark || - state.length === 0); -} + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; -// backwards compatibility. -Readable.prototype.setEncoding = function(enc) { - if (!StringDecoder) - StringDecoder = require('string_decoder/').StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; return this; }; -// Don't raise the hwm > 128MB -var MAX_HWM = 0x800000; -function roundUpToNextPowerOf2(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 - n--; - for (var p = 1; p < 32; p <<= 1) n |= n >> p; - n++; - } - return n; -} - -function howMuchToRead(n, state) { - if (state.length === 0 && state.ended) - return 0; +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; - if (state.objectMode) - return n === 0 ? 0 : 1; +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; - if (isNaN(n) || util.isNull(n)) { - // only flow one buffer at a time - if (state.flowing && state.buffer.length) - return state.buffer[0].length; - else - return state.length; + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; } + return 0; +}; - if (n <= 0) - return 0; +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; - // If we're asking for more than the target buffer level, - // then raise the water mark. Bump up to the next highest - // power of 2, to prevent increasing it excessively in tiny - // amounts. - if (n > state.highWaterMark) - state.highWaterMark = roundUpToNextPowerOf2(n); - - // don't have that much. return null, unless we've ended. - if (n > state.length) { - if (!state.ended) { - state.needReadable = true; - return 0; - } else - return state.length; - } - - return n; +function isFunction(arg) { + return typeof arg === 'function'; } -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function(n) { - debug('read', n); - var state = this._readableState; - var nOrig = n; - - if (!util.isNumber(n) || n > 0) - state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && - state.needReadable && - (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) - endReadable(this); - else - emitReadable(this); - return null; - } +function isNumber(arg) { + return typeof arg === 'number'; +} - n = howMuchToRead(n, state); +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) - endReadable(this); - return null; - } +function isUndefined(arg) { + return arg === void 0; +} - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. +},{}],49:[function(require,module,exports){ +(function (process){ +// Growl - Copyright TJ Holowaychuk (MIT Licensed) - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); +/** + * Module dependencies. + */ - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } +var exec = require('child_process').exec + , fs = require('fs') + , path = require('path') + , exists = fs.existsSync || path.existsSync + , os = require('os') + , quote = JSON.stringify + , cmd; - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } +function which(name) { + var paths = process.env.PATH.split(':'); + var loc; - if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) - state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; + for (var i = 0, len = paths.length; i < len; ++i) { + loc = path.join(paths[i], name); + if (exists(loc)) return loc; } +} - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (doRead && !state.reading) - n = howMuchToRead(nOrig, state); - - var ret; - if (n > 0) - ret = fromList(n, state); - else - ret = null; +switch(os.type()) { + case 'Darwin': + if (which('terminal-notifier')) { + cmd = { + type: "Darwin-NotificationCenter" + , pkg: "terminal-notifier" + , msg: '-message' + , title: '-title' + , subtitle: '-subtitle' + , icon: '-appIcon' + , sound: '-sound' + , url: '-open' + , priority: { + cmd: '-execute' + , range: [] + } + }; + } else { + cmd = { + type: "Darwin-Growl" + , pkg: "growlnotify" + , msg: '-m' + , sticky: '--sticky' + , priority: { + cmd: '--priority' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + , "Very Low" + , "Moderate" + , "Normal" + , "High" + , "Emergency" + ] + } + }; + } + break; + case 'Linux': + if (which('growl')) { + cmd = { + type: "Linux-Growl" + , pkg: "growl" + , msg: '-m' + , title: '-title' + , subtitle: '-subtitle' + , host: { + cmd: '-H' + , hostname: '192.168.33.1' + } + }; + } else { + cmd = { + type: "Linux" + , pkg: "notify-send" + , msg: '' + , sticky: '-t 0' + , icon: '-i' + , priority: { + cmd: '-u' + , range: [ + "low" + , "normal" + , "critical" + ] + } + }; + } + break; + case 'Windows_NT': + cmd = { + type: "Windows" + , pkg: "growlnotify" + , msg: '' + , sticky: '/s:true' + , title: '/t:' + , icon: '/i:' + , url: '/cu:' + , priority: { + cmd: '/p:' + , range: [ + -2 + , -1 + , 0 + , 1 + , 2 + ] + } + }; + break; +} - if (util.isNull(ret)) { - state.needReadable = true; - n = 0; - } +/** + * Expose `growl`. + */ - state.length -= n; +exports = module.exports = growl; - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (state.length === 0 && !state.ended) - state.needReadable = true; +/** + * Node-growl version. + */ - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended && state.length === 0) - endReadable(this); +exports.version = '1.4.1' - if (!util.isNull(ret)) - this.emit('data', ret); +/** + * Send growl notification _msg_ with _options_. + * + * Options: + * + * - title Notification title + * - sticky Make the notification stick (defaults to false) + * - priority Specify an int or named key (default is 0) + * - name Application name (defaults to growlnotify) + * - sound Sound efect ( in OSx defined in preferences -> sound -> effects) * works only in OSX > 10.8x + * - image + * - path to an icon sets --iconpath + * - path to an image sets --image + * - capitalized word sets --appIcon + * - filename uses extname as --icon + * - otherwise treated as --icon + * + * Examples: + * + * growl('New email') + * growl('5 new emails', { title: 'Thunderbird' }) + * growl('5 new emails', { title: 'Thunderbird', sound: 'Purr' }) + * growl('Email sent', function(){ + * // ... notification sent + * }) + * + * @param {string} msg + * @param {object} options + * @param {function} fn + * @api public + */ - return ret; -}; +function growl(msg, options, fn) { + var image + , args + , options = options || {} + , fn = fn || function(){}; -function chunkInvalid(state, chunk) { - var er = null; - if (!util.isBuffer(chunk) && - !util.isString(chunk) && - !util.isNullOrUndefined(chunk) && - !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); + if (options.exec) { + cmd = { + type: "Custom" + , pkg: options.exec + , range: [] + }; } - return er; -} - -function onEofChunk(stream, state) { - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; + // noop + if (!cmd) return fn(new Error('growl not supported on this platform')); + args = [cmd.pkg]; - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - if (state.sync) - process.nextTick(function() { - emitReadable_(stream); - }); - else - emitReadable_(stream); + // image + if (image = options.image) { + switch(cmd.type) { + case 'Darwin-Growl': + var flag, ext = path.extname(image).substr(1) + flag = flag || ext == 'icns' && 'iconpath' + flag = flag || /^[A-Z]/.test(image) && 'appIcon' + flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' + flag = flag || ext && (image = ext) && 'icon' + flag = flag || 'icon' + args.push('--' + flag, quote(image)) + break; + case 'Darwin-NotificationCenter': + args.push(cmd.icon, quote(image)); + break; + case 'Linux': + args.push(cmd.icon, quote(image)); + // libnotify defaults to sticky, set a hint for transient notifications + if (!options.sticky) args.push('--hint=int:transient:1'); + break; + case 'Windows': + args.push(cmd.icon + quote(image)); + break; + } } -} - -function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} + // sticky + if (options.sticky) args.push(cmd.sticky); -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - process.nextTick(function() { - maybeReadMore_(stream, state); - }); + // priority + if (options.priority) { + var priority = options.priority + ''; + var checkindexOf = cmd.priority.range.indexOf(priority); + if (~cmd.priority.range.indexOf(priority)) { + args.push(cmd.priority, options.priority); + } } -} -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && - state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break; - else - len = state.length; + //sound + if(options.sound && cmd.type === 'Darwin-NotificationCenter'){ + args.push(cmd.sound, options.sound) } - state.readingMore = false; -} - -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function(n) { - this.emit('error', new Error('not implemented')); -}; -Readable.prototype.pipe = function(dest, pipeOpts) { - var src = this; - var state = this._readableState; + // name + if (options.name && cmd.type === "Darwin-Growl") { + args.push('--name', options.name); + } - switch (state.pipesCount) { - case 0: - state.pipes = dest; + switch(cmd.type) { + case 'Darwin-Growl': + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(quote(options.title)); break; - case 1: - state.pipes = [state.pipes, dest]; + case 'Darwin-NotificationCenter': + args.push(cmd.msg); + var stringifiedMsg = quote(msg); + var escapedMsg = stringifiedMsg.replace(/\\n/g, '\n'); + args.push(escapedMsg); + if (options.title) { + args.push(cmd.title); + args.push(quote(options.title)); + } + if (options.subtitle) { + args.push(cmd.subtitle); + args.push(quote(options.subtitle)); + } + if (options.url) { + args.push(cmd.url); + args.push(quote(options.url)); + } break; - default: - state.pipes.push(dest); + case 'Linux-Growl': + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(quote(options.title)); + if (cmd.host) { + args.push(cmd.host.cmd, cmd.host.hostname) + } + break; + case 'Linux': + if (options.title) { + args.push(quote(options.title)); + args.push(cmd.msg); + args.push(quote(msg).replace(/\\n/g, '\n')); + } else { + args.push(quote(msg).replace(/\\n/g, '\n')); + } + break; + case 'Windows': + args.push(quote(msg).replace(/\\n/g, '\n')); + if (options.title) args.push(cmd.title + quote(options.title)); + if (options.url) args.push(cmd.url + quote(options.url)); + break; + case 'Custom': + args[0] = (function(origCommand) { + var message = options.title + ? options.title + ': ' + msg + : msg; + var command = origCommand.replace(/(^|[^%])%s/g, '$1' + quote(message)); + if (command === origCommand) args.push(quote(message)); + return command; + })(args[0]); break; } - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - var doEnd = (!pipeOpts || pipeOpts.end !== false) && - dest !== process.stdout && - dest !== process.stderr; + // execute + exec(args.join(' '), fn); +}; - var endFn = doEnd ? onend : cleanup; - if (state.endEmitted) - process.nextTick(endFn); - else - src.once('end', endFn); +}).call(this,require('_process')) +},{"_process":57,"child_process":43,"fs":43,"os":55,"path":43}],50:[function(require,module,exports){ +exports.read = function (buffer, offset, isLE, mLen, nBytes) { + var e, m + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var nBits = -7 + var i = isLE ? (nBytes - 1) : 0 + var d = isLE ? -1 : 1 + var s = buffer[offset + i] - dest.on('unpipe', onunpipe); - function onunpipe(readable) { - debug('onunpipe'); - if (readable === src) { - cleanup(); - } - } + i += d - function onend() { - debug('onend'); - dest.end(); + e = s & ((1 << (-nBits)) - 1) + s >>= (-nBits) + nBits += eLen + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + m = e & ((1 << (-nBits)) - 1) + e >>= (-nBits) + nBits += mLen + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {} + + if (e === 0) { + e = 1 - eBias + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity) + } else { + m = m + Math.pow(2, mLen) + e = e - eBias } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen) +} - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); +exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c + var eLen = nBytes * 8 - mLen - 1 + var eMax = (1 << eLen) - 1 + var eBias = eMax >> 1 + var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0) + var i = isLE ? 0 : (nBytes - 1) + var d = isLE ? 1 : -1 + var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0 - function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', cleanup); - src.removeListener('data', ondata); + value = Math.abs(value) - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (state.awaitDrain && - (!dest._writableState || dest._writableState.needDrain)) - ondrain(); - } + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0 + e = eMax + } else { + e = Math.floor(Math.log(value) / Math.LN2) + if (value * (c = Math.pow(2, -e)) < 1) { + e-- + c *= 2 + } + if (e + eBias >= 1) { + value += rt / c + } else { + value += rt * Math.pow(2, 1 - eBias) + } + if (value * c >= 2) { + e++ + c /= 2 + } - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - var ret = dest.write(chunk); - if (false === ret) { - debug('false write response, pause', - src._readableState.awaitDrain); - src._readableState.awaitDrain++; - src.pause(); + if (e + eBias >= eMax) { + m = 0 + e = eMax + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen) + e = e + eBias + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen) + e = 0 } } - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EE.listenerCount(dest, 'error') === 0) - dest.emit('error', er); - } - // This is a brutally ugly hack to make sure that our error handler - // is attached before any userland ones. NEVER DO THIS. - if (!dest._events || !dest._events.error) - dest.on('error', onerror); - else if (isArray(dest._events.error)) - dest._events.error.unshift(onerror); - else - dest._events.error = [onerror, dest._events.error]; + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} + e = (e << mLen) | m + eLen += mLen + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} + buffer[offset + i - d] |= s * 128 +} - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); +},{}],51:[function(require,module,exports){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor } - dest.once('finish', onfinish); +} - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } +},{}],52:[function(require,module,exports){ +/** + * Determine if an object is Buffer + * + * Author: Feross Aboukhadijeh + * License: MIT + * + * `npm install is-buffer` + */ - // tell the dest that it's being piped to - dest.emit('pipe', src); +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } +},{}],53:[function(require,module,exports){ +var toString = {}.toString; - return dest; +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; }; -function pipeOnDrain(src) { - return function() { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) - state.awaitDrain--; - if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { - state.flowing = true; - flow(src); +},{}],54:[function(require,module,exports){ +(function (process){ +var path = require('path'); +var fs = require('fs'); +var _0777 = parseInt('0777', 8); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, opts, f, made) { + if (typeof opts === 'function') { + f = opts; + opts = {}; } - }; + else if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; + + var cb = f || function () {}; + p = path.resolve(p); + + xfs.mkdir(p, mode, function (er) { + if (!er) { + made = made || p; + return cb(null, made); + } + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), opts, function (er, made) { + if (er) cb(er, made); + else mkdirP(p, opts, cb, made); + }); + break; + + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + xfs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original error be the failure reason. + if (er2 || !stat.isDirectory()) cb(er, made) + else cb(null, made); + }); + break; + } + }); } +mkdirP.sync = function sync (p, opts, made) { + if (!opts || typeof opts !== 'object') { + opts = { mode: opts }; + } + + var mode = opts.mode; + var xfs = opts.fs || fs; + + if (mode === undefined) { + mode = _0777 & (~process.umask()); + } + if (!made) made = null; -Readable.prototype.unpipe = function(dest) { - var state = this._readableState; + p = path.resolve(p); - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) - return this; + try { + xfs.mkdirSync(p, mode); + made = made || p; + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + made = sync(path.dirname(p), opts, made); + sync(p, opts, made); + break; - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) - return this; + // In the case of any other error, just see if there's a dir + // there already. If so, then hooray! If not, then something + // is borked. + default: + var stat; + try { + stat = xfs.statSync(p); + } + catch (err1) { + throw err0; + } + if (!stat.isDirectory()) throw err0; + break; + } + } - if (!dest) - dest = state.pipes; + return made; +}; - // got a match. - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) - dest.emit('unpipe', this); - return this; - } +}).call(this,require('_process')) +},{"_process":57,"fs":43,"path":43}],55:[function(require,module,exports){ +exports.endianness = function () { return 'LE' }; - // slow case. multiple pipe destinations. +exports.hostname = function () { + if (typeof location !== 'undefined') { + return location.hostname + } + else return ''; +}; - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; +exports.loadavg = function () { return [] }; - for (var i = 0; i < len; i++) - dests[i].emit('unpipe', this); - return this; - } +exports.uptime = function () { return 0 }; - // try to find the right one. - var i = indexOf(state.pipes, dest); - if (i === -1) - return this; +exports.freemem = function () { + return Number.MAX_VALUE; +}; - state.pipes.splice(i, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) - state.pipes = state.pipes[0]; +exports.totalmem = function () { + return Number.MAX_VALUE; +}; - dest.emit('unpipe', this); +exports.cpus = function () { return [] }; - return this; +exports.type = function () { return 'Browser' }; + +exports.release = function () { + if (typeof navigator !== 'undefined') { + return navigator.appVersion; + } + return ''; }; -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function(ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); +exports.networkInterfaces += exports.getNetworkInterfaces += function () { return {} }; - // If listening to data, and it has not explicitly been paused, - // then call resume to start the flow of data on the next tick. - if (ev === 'data' && false !== this._readableState.flowing) { - this.resume(); - } +exports.arch = function () { return 'javascript' }; - if (ev === 'readable' && this.readable) { - var state = this._readableState; - if (!state.readableListening) { - state.readableListening = true; - state.emittedReadable = false; - state.needReadable = true; - if (!state.reading) { - var self = this; - process.nextTick(function() { - debug('readable nexttick read 0'); - self.read(0); - }); - } else if (state.length) { - emitReadable(this, state); - } - } - } +exports.platform = function () { return 'browser' }; - return res; +exports.tmpdir = exports.tmpDir = function () { + return '/tmp'; }; -Readable.prototype.addListener = Readable.prototype.on; -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function() { - var state = this._readableState; - if (!state.flowing) { - debug('resume'); - state.flowing = true; - if (!state.reading) { - debug('resume read 0'); - this.read(0); - } - resume(this, state); - } - return this; -}; +exports.EOL = '\n'; -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - process.nextTick(function() { - resume_(stream, state); +},{}],56:[function(require,module,exports){ +(function (process){ +'use strict'; + +if (!process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = nextTick; +} else { + module.exports = process.nextTick; +} + +function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); + } + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); }); } } -function resume_(stream, state) { - state.resumeScheduled = false; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) - stream.read(0); -} +}).call(this,require('_process')) +},{"_process":57}],57:[function(require,module,exports){ +// shim for using process in browser -Readable.prototype.pause = function() { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; +var process = module.exports = {}; +var queue = []; +var draining = false; +var currentQueue; +var queueIndex = -1; -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - if (state.flowing) { - do { - var chunk = stream.read(); - } while (null !== chunk && state.flowing); - } +function cleanUpNextTick() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } } -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function(stream) { - var state = this._readableState; - var paused = false; +function drainQueue() { + if (draining) { + return; + } + var timeout = setTimeout(cleanUpNextTick); + draining = true; - var self = this; - stream.on('end', function() { - debug('wrapped end'); - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) - self.push(chunk); + var len = queue.length; + while(len) { + currentQueue = queue; + queue = []; + while (++queueIndex < len) { + if (currentQueue) { + currentQueue[queueIndex].run(); + } + } + queueIndex = -1; + len = queue.length; } + currentQueue = null; + draining = false; + clearTimeout(timeout); +} - self.push(null); - }); +process.nextTick = function (fun) { + var args = new Array(arguments.length - 1); + if (arguments.length > 1) { + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + } + queue.push(new Item(fun, args)); + if (queue.length === 1 && !draining) { + setTimeout(drainQueue, 0); + } +}; - stream.on('data', function(chunk) { - debug('wrapped data'); - if (state.decoder) - chunk = state.decoder.write(chunk); - if (!chunk || !state.objectMode && !chunk.length) - return; +// v8 likes predictible objects +function Item(fun, array) { + this.fun = fun; + this.array = array; +} +Item.prototype.run = function () { + this.fun.apply(null, this.array); +}; +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; +process.version = ''; // empty string to avoid regexp issues +process.versions = {}; - var ret = self.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); +function noop() {} - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { - this[i] = function(method) { return function() { - return stream[method].apply(stream, arguments); - }}(i); - } - } +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; - // proxy certain important events. - var events = ['error', 'close', 'destroy', 'pause', 'resume']; - forEach(events, function(ev) { - stream.on(ev, self.emit.bind(self, ev)); - }); +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; - // when we try to consume some more bytes, simply unpause the - // underlying stream. - self._read = function(n) { - debug('wrapped _read', n); - if (paused) { - paused = false; - stream.resume(); - } - }; +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; - return self; +},{}],58:[function(require,module,exports){ +module.exports = require("./lib/_stream_duplex.js") + +},{"./lib/_stream_duplex.js":59}],59:[function(require,module,exports){ +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +'use strict'; + +/**/ + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + keys.push(key); + }return keys; }; +/**/ +module.exports = Duplex; +/**/ +var processNextTick = require('process-nextick-args'); +/**/ -// exposed for testing purposes only. -Readable._fromList = fromList; +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -function fromList(n, state) { - var list = state.buffer; - var length = state.length; - var stringMode = !!state.decoder; - var objectMode = !!state.objectMode; - var ret; +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); - // nothing in the list, definitely empty. - if (list.length === 0) - return null; +util.inherits(Duplex, Readable); - if (length === 0) - ret = null; - else if (objectMode) - ret = list.shift(); - else if (!n || n >= length) { - // read it all, truncate the array. - if (stringMode) - ret = list.join(''); - else - ret = Buffer.concat(list, length); - list.length = 0; - } else { - // read just some of it. - if (n < list[0].length) { - // just take a part of the first list item. - // slice is the same for buffers and strings. - var buf = list[0]; - ret = buf.slice(0, n); - list[0] = buf.slice(n); - } else if (n === list[0].length) { - // first list is a perfect match - ret = list.shift(); - } else { - // complex case. - // we have enough to cover it, but it spans past the first buffer. - if (stringMode) - ret = ''; - else - ret = new Buffer(n); +var keys = objectKeys(Writable.prototype); +for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; +} - var c = 0; - for (var i = 0, l = list.length; i < l && c < n; i++) { - var buf = list[0]; - var cpy = Math.min(n - c, buf.length); +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); - if (stringMode) - ret += buf.slice(0, cpy); - else - buf.copy(ret, c, 0, cpy); + Readable.call(this, options); + Writable.call(this, options); - if (cpy < buf.length) - list[0] = buf.slice(cpy); - else - list.shift(); + if (options && options.readable === false) this.readable = false; - c += cpy; - } - } - } + if (options && options.writable === false) this.writable = false; - return ret; + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); } -function endReadable(stream) { - var state = stream._readableState; +// the no-half-open enforcer +function onend() { + // if we allow half-open state, or if the writable side ended, + // then we're ok. + if (this.allowHalfOpen || this._writableState.ended) return; - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) - throw new Error('endReadable called on non-empty stream'); + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} - if (!state.endEmitted) { - state.ended = true; - process.nextTick(function() { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } - }); - } +function onEndNT(self) { + self.end(); } -function forEach (xs, f) { +function forEach(xs, f) { for (var i = 0, l = xs.length; i < l; i++) { f(xs[i], i); } } +},{"./_stream_readable":61,"./_stream_writable":63,"core-util-is":45,"inherits":51,"process-nextick-args":56}],60:[function(require,module,exports){ +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. -function indexOf (xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} +'use strict'; -}).call(this,require('_process')) -},{"./_stream_duplex":53,"_process":51,"buffer":43,"core-util-is":58,"events":47,"inherits":48,"isarray":49,"stream":63,"string_decoder/":64,"util":42}],56:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +module.exports = PassThrough; - -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - -module.exports = Transform; - -var Duplex = require('./_stream_duplex'); +var Transform = require('./_stream_transform'); /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ -util.inherits(Transform, Duplex); - - -function TransformState(options, stream) { - this.afterTransform = function(er, data) { - return afterTransform(stream, er, data); - }; - - this.needTransform = false; - this.transforming = false; - this.writecb = null; - this.writechunk = null; -} - -function afterTransform(stream, er, data) { - var ts = stream._transformState; - ts.transforming = false; - - var cb = ts.writecb; - - if (!cb) - return stream.emit('error', new Error('no writecb in Transform class')); - - ts.writechunk = null; - ts.writecb = null; - - if (!util.isNullOrUndefined(data)) - stream.push(data); - - if (cb) - cb(er); - - var rs = stream._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - stream._read(rs.highWaterMark); - } -} - - -function Transform(options) { - if (!(this instanceof Transform)) - return new Transform(options); - - Duplex.call(this, options); - - this._transformState = new TransformState(options, this); - - // when the writable side finishes, then flush out anything remaining. - var stream = this; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; +util.inherits(PassThrough, Transform); - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; +function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); - this.once('prefinish', function() { - if (util.isFunction(this._flush)) - this._flush(function(er) { - done(stream, er); - }); - else - done(stream); - }); + Transform.call(this, options); } -Transform.prototype.push = function(chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function(chunk, encoding, cb) { - throw new Error('not implemented'); -}; - -Transform.prototype._write = function(chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || - rs.needReadable || - rs.length < rs.highWaterMark) - this._read(rs.highWaterMark); - } -}; - -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function(n) { - var ts = this._transformState; - - if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } +PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); }; +},{"./_stream_transform":62,"core-util-is":45,"inherits":51}],61:[function(require,module,exports){ +(function (process){ +'use strict'; +module.exports = Readable; -function done(stream, er) { - if (er) - return stream.emit('error', er); - - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - var ws = stream._writableState; - var ts = stream._transformState; - - if (ws.length) - throw new Error('calling transform done when ws.length != 0'); - - if (ts.transforming) - throw new Error('calling transform done when still transforming'); +/**/ +var processNextTick = require('process-nextick-args'); +/**/ - return stream.push(null); -} +/**/ +var isArray = require('isarray'); +/**/ -},{"./_stream_duplex":53,"core-util-is":58,"inherits":48}],57:[function(require,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. +/**/ +var Buffer = require('buffer').Buffer; +/**/ -// A bit simpler than readable streams. -// Implement an async ._write(chunk, cb), and it'll handle all -// the drain event emission and buffering. +Readable.ReadableState = ReadableState; -module.exports = Writable; +var EE = require('events'); /**/ -var Buffer = require('buffer').Buffer; +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; /**/ -Writable.WritableState = WritableState; +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ +var Buffer = require('buffer').Buffer; /**/ var util = require('core-util-is'); util.inherits = require('inherits'); /**/ -var Stream = require('stream'); +/**/ +var debugUtil = require('util'); +var debug = undefined; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ -util.inherits(Writable, Stream); +var StringDecoder; -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; -} +util.inherits(Readable, Stream); -function WritableState(options, stream) { - var Duplex = require('./_stream_duplex'); +var Duplex; +function ReadableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); options = options || {}; - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var defaultHwm = options.objectMode ? 16 : 16 * 1024; - this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away this.objectMode = !!options.objectMode; - if (stream instanceof Duplex) - this.objectMode = this.objectMode || !!options.writableObjectMode; + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.readableObjectMode; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + this.highWaterMark = ~ ~this.highWaterMark; - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; this.ended = false; - // when 'finish' is emitted - this.finished = false; + this.endEmitted = false; + this.reading = false; - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. // Everything else in the universe uses 'utf8', though. this.defaultEncoding = options.defaultEncoding || 'utf8'; - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; - // a flag to see when we're in the middle of a write. - this.writing = false; + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; - // when true all writes will be buffered until .uncork() call - this.corked = 0; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // the callback that's passed to _write(chunk,cb) - this.onwrite = function(er) { - onwrite(stream, er); - }; - - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - - // the amount that is being written when _write is called. - this.writelen = 0; - - this.buffer = []; - - // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - - // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - this.prefinished = false; + // if true, a maybeReadMore has been scheduled + this.readingMore = false; - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } } -function Writable(options) { - var Duplex = require('./_stream_duplex'); - - // Writable ctor is applied to Duplexes, though they're not - // instanceof Writable, they're instanceof Readable. - if (!(this instanceof Writable) && !(this instanceof Duplex)) - return new Writable(options); - - this._writableState = new WritableState(options, this); - - // legacy. - this.writable = true; +var Duplex; +function Readable(options) { + Duplex = Duplex || require('./_stream_duplex'); - Stream.call(this); -} + if (!(this instanceof Readable)) return new Readable(options); -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function() { - this.emit('error', new Error('Cannot pipe. Not readable.')); -}; + this._readableState = new ReadableState(options, this); + // legacy + this.readable = true; -function writeAfterEnd(stream, state, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - process.nextTick(function() { - cb(er); - }); -} + if (options && typeof options.read === 'function') this._read = options.read; -// If we get something that is not a buffer, string, null, or undefined, -// and we're not in objectMode, then that's an error. -// Otherwise stream chunks are all considered to be of length=1, and the -// watermarks determine how many objects to keep in the buffer, rather than -// how many bytes or characters. -function validChunk(stream, state, chunk, cb) { - var valid = true; - if (!util.isBuffer(chunk) && - !util.isString(chunk) && - !util.isNullOrUndefined(chunk) && - !state.objectMode) { - var er = new TypeError('Invalid non-string/buffer chunk'); - stream.emit('error', er); - process.nextTick(function() { - cb(er); - }); - valid = false; - } - return valid; + Stream.call(this); } -Writable.prototype.write = function(chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - - if (util.isFunction(encoding)) { - cb = encoding; - encoding = null; - } - - if (util.isBuffer(chunk)) - encoding = 'buffer'; - else if (!encoding) - encoding = state.defaultEncoding; - - if (!util.isFunction(cb)) - cb = function() {}; +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; - if (state.ended) - writeAfterEnd(this, state, cb); - else if (validChunk(this, state, chunk, cb)) { - state.pendingcb++; - ret = writeOrBuffer(this, state, chunk, encoding, cb); + if (!state.objectMode && typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } } - return ret; + return readableAddChunk(this, state, chunk, encoding, false); }; -Writable.prototype.cork = function() { - var state = this._writableState; - - state.corked++; +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); }; -Writable.prototype.uncork = function() { - var state = this._writableState; - - if (state.corked) { - state.corked--; - - if (!state.writing && - !state.corked && - !state.finished && - !state.bufferProcessing && - state.buffer.length) - clearBuffer(this, state); - } +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; }; -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && - state.decodeStrings !== false && - util.isString(chunk)) { - chunk = new Buffer(chunk, encoding); - } - return chunk; -} +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + var skipAdd; + if (state.decoder && !addToFront && !encoding) { + chunk = state.decoder.write(chunk); + skipAdd = !state.objectMode && chunk.length === 0; + } -// if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, chunk, encoding, cb) { - chunk = decodeChunk(state, chunk, encoding); - if (util.isBuffer(chunk)) - encoding = 'buffer'; - var len = state.objectMode ? 1 : chunk.length; + if (!addToFront) state.reading = false; - state.length += len; + // Don't add to the buffer if we've decoded to an empty string chunk and + // we're not in object mode + if (!skipAdd) { + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. - if (!ret) - state.needDrain = true; + if (state.needReadable) emitReadable(stream); + } + } - if (state.writing || state.corked) - state.buffer.push(new WriteReq(chunk, encoding, cb)); - else - doWrite(stream, state, false, len, chunk, encoding, cb); + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } - return ret; + return needMoreData(state); } -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) - stream._writev(chunk, state.onwrite); - else - stream._write(chunk, encoding, state.onwrite); - state.sync = false; +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); } -function onwriteError(stream, state, sync, er, cb) { - if (sync) - process.nextTick(function() { - state.pendingcb--; - cb(er); - }); - else { - state.pendingcb--; - cb(er); - } +// backwards compatibility. +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; - stream._writableState.errorEmitted = true; - stream.emit('error', er); +// Don't raise the hwm > 8MB +var MAX_HWM = 0x800000; +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + return n; } -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) return 0; -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; + if (state.objectMode) return n === 0 ? 0 : 1; - onwriteStateUpdate(state); + if (n === null || isNaN(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) return state.buffer[0].length;else return state.length; + } - if (er) - onwriteError(stream, state, sync, er, cb); - else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(stream, state); + if (n <= 0) return 0; - if (!finished && - !state.corked && - !state.bufferProcessing && - state.buffer.length) { - clearBuffer(stream, state); - } + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (sync) { - process.nextTick(function() { - afterWrite(stream, state, finished, cb); - }); + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; } else { - afterWrite(stream, state, finished, cb); + return state.length; } } -} -function afterWrite(stream, state, finished, cb) { - if (!finished) - onwriteDrain(stream, state); - state.pendingcb--; - cb(); - finishMaybe(stream, state); + return n; } -// Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } -} +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function (n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; + if (typeof n !== 'number' || n > 0) state.emittedReadable = false; -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } - if (stream._writev && state.buffer.length > 1) { - // Fast case, write everything using _writev() - var cbs = []; - for (var c = 0; c < state.buffer.length; c++) - cbs.push(state.buffer[c].callback); + n = howMuchToRead(n, state); - // count the one we are adding, as well. - // TODO(isaacs) clean this up - state.pendingcb++; - doWrite(stream, state, true, state.length, state.buffer, '', function(err) { - for (var i = 0; i < cbs.length; i++) { - state.pendingcb--; - cbs[i](err); - } - }); + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } - // Clear buffer - state.buffer = []; - } else { - // Slow case, write chunks one-by-one - for (var c = 0; c < state.buffer.length; c++) { - var entry = state.buffer[c]; - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, false, len, chunk, encoding, cb); + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. - // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - c++; - break; - } - } + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); - if (c < state.buffer.length) - state.buffer = state.buffer.slice(c); - else - state.buffer.length = 0; + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); } - state.bufferProcessing = false; -} - -Writable.prototype._write = function(chunk, encoding, cb) { - cb(new Error('not implemented')); + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } -}; + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } -Writable.prototype._writev = null; + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) n = howMuchToRead(nOrig, state); -Writable.prototype.end = function(chunk, encoding, cb) { - var state = this._writableState; + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; - if (util.isFunction(chunk)) { - cb = chunk; - chunk = null; - encoding = null; - } else if (util.isFunction(encoding)) { - cb = encoding; - encoding = null; + if (ret === null) { + state.needReadable = true; + n = 0; } - if (!util.isNullOrUndefined(chunk)) - this.write(chunk, encoding); - - // .end() fully uncorks - if (state.corked) { - state.corked = 1; - this.uncork(); - } + state.length -= n; - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) - endWritable(this, state, cb); -}; + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) state.needReadable = true; + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) endReadable(this); -function needFinish(stream, state) { - return (state.ending && - state.length === 0 && - !state.finished && - !state.writing); -} + if (ret !== null) this.emit('data', ret); -function prefinish(stream, state) { - if (!state.prefinished) { - state.prefinished = true; - stream.emit('prefinish'); - } -} + return ret; +}; -function finishMaybe(stream, state) { - var need = needFinish(stream, state); - if (need) { - if (state.pendingcb === 0) { - prefinish(stream, state); - state.finished = true; - stream.emit('finish'); - } else - prefinish(stream, state); +function chunkInvalid(state, chunk) { + var er = null; + if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); } - return need; + return er; } -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) - process.nextTick(cb); - else - stream.once('finish', cb); +function onEofChunk(stream, state) { + if (state.ended) return; + if (state.decoder) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } } state.ended = true; -} - -}).call(this,require('_process')) -},{"./_stream_duplex":53,"_process":51,"buffer":43,"core-util-is":58,"inherits":48,"stream":63}],58:[function(require,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); } -exports.isArray = isArray; -function isBoolean(arg) { - return typeof arg === 'boolean'; +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) processNextTick(emitReadable_, stream);else emitReadable_(stream); + } } -exports.isBoolean = isBoolean; -function isNull(arg) { - return arg === null; +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); } -exports.isNull = isNull; -function isNullOrUndefined(arg) { - return arg == null; +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + processNextTick(maybeReadMore_, stream, state); + } } -exports.isNullOrUndefined = isNullOrUndefined; -function isNumber(arg) { - return typeof arg === 'number'; +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break;else len = state.length; + } + state.readingMore = false; } -exports.isNumber = isNumber; -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function (n) { + this.emit('error', new Error('not implemented')); +}; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; + function onend() { + debug('onend'); + dest.end(); + } -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; - -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); -function isBuffer(arg) { - return Buffer.isBuffer(arg); -} -exports.isBuffer = isBuffer; + var cleanedUp = false; + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); -function objectToString(o) { - return Object.prototype.toString.call(o); -} -}).call(this,require("buffer").Buffer) -},{"buffer":43}],59:[function(require,module,exports){ -module.exports = require("./lib/_stream_passthrough.js") + cleanedUp = true; -},{"./lib/_stream_passthrough.js":54}],60:[function(require,module,exports){ -exports = module.exports = require('./lib/_stream_readable.js'); -exports.Stream = require('stream'); -exports.Readable = exports; -exports.Writable = require('./lib/_stream_writable.js'); -exports.Duplex = require('./lib/_stream_duplex.js'); -exports.Transform = require('./lib/_stream_transform.js'); -exports.PassThrough = require('./lib/_stream_passthrough.js'); + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } -},{"./lib/_stream_duplex.js":53,"./lib/_stream_passthrough.js":54,"./lib/_stream_readable.js":55,"./lib/_stream_transform.js":56,"./lib/_stream_writable.js":57,"stream":63}],61:[function(require,module,exports){ -module.exports = require("./lib/_stream_transform.js") + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + if (state.pipesCount === 1 && state.pipes[0] === dest && src.listenerCount('data') === 1 && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + } + src.pause(); + } + } -},{"./lib/_stream_transform.js":56}],62:[function(require,module,exports){ -module.exports = require("./lib/_stream_writable.js") + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) dest.on('error', onerror);else if (isArray(dest._events.error)) dest._events.error.unshift(onerror);else dest._events.error = [onerror, dest._events.error]; -},{"./lib/_stream_writable.js":57}],63:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); -module.exports = Stream; + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } -var EE = require('events').EventEmitter; -var inherits = require('inherits'); + // tell the dest that it's being piped to + dest.emit('pipe', src); -inherits(Stream, EE); -Stream.Readable = require('readable-stream/readable.js'); -Stream.Writable = require('readable-stream/writable.js'); -Stream.Duplex = require('readable-stream/duplex.js'); -Stream.Transform = require('readable-stream/transform.js'); -Stream.PassThrough = require('readable-stream/passthrough.js'); + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; + return dest; +}; +function pipeOnDrain(src) { + return function () { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return this; -function Stream() { - EE.call(this); -} + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; -Stream.prototype.pipe = function(dest, options) { - var source = this; + if (!dest) dest = state.pipes; - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this); + return this; } - source.on('data', ondata); - - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } + // slow case. multiple pipe destinations. - dest.on('drain', ondrain); + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); + for (var _i = 0; _i < len; _i++) { + dests[_i].emit('unpipe', this); + }return this; } - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) return this; - dest.end(); - } + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + dest.emit('unpipe', this); - function onclose() { - if (didOnEnd) return; - didOnEnd = true; + return this; +}; - if (typeof dest.destroy === 'function') dest.destroy(); +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); } - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. + if (ev === 'readable' && !this._readableState.endEmitted) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + processNextTick(nReadingNextTick, this); + } else if (state.length) { + emitReadable(this, state); + } } } - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; - source.removeListener('end', onend); - source.removeListener('close', onclose); +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} - source.removeListener('error', onerror); - dest.removeListener('error', onerror); +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function () { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + resume(this, state); + } + return this; +}; - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + processNextTick(resume_, stream, state); + } +} - dest.removeListener('close', cleanup); +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); } - source.on('end', cleanup); - source.on('close', cleanup); + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} - dest.on('close', cleanup); +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; - dest.emit('pipe', source); +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function (stream) { + var state = this._readableState; + var paused = false; -},{"events":47,"inherits":48,"readable-stream/duplex.js":52,"readable-stream/passthrough.js":59,"readable-stream/readable.js":60,"readable-stream/transform.js":61,"readable-stream/writable.js":62}],64:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + var self = this; + stream.on('end', function () { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) self.push(chunk); + } -var Buffer = require('buffer').Buffer; + self.push(null); + }); -var isBufferEncoding = Buffer.isEncoding - || function(encoding) { - switch (encoding && encoding.toLowerCase()) { - case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; - default: return false; - } - } + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); + // don't skip over falsy values in objectMode + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; -function assertEncoding(encoding) { - if (encoding && !isBufferEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. CESU-8 is handled as part of the UTF-8 encoding. -// -// @TODO Handling all encodings inside a single object makes it very difficult -// to reason about this code, so it should be split up in the future. -// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code -// points as used by CESU-8. -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function (method) { + return function () { + return stream[method].apply(stream, arguments); + }; + }(i); + } } - // Enough space to store all bytes of a single character. UTF-8 needs 4 - // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). - this.charBuffer = new Buffer(6); - // Number of bytes received for the current incomplete multi-byte character. - this.charReceived = 0; - // Number of bytes expected for the current incomplete multi-byte character. - this.charLength = 0; + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function (ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function (n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; }; +// exposed for testing purposes only. +Readable._fromList = fromList; -// write decodes the given buffer and returns it as JS string that is -// guaranteed to not contain any partial multi-byte characters. Any partial -// character found at the end of the buffer is buffered up, and will be -// returned when calling write again with the remaining bytes. -// -// Note: Converting a Buffer containing an orphan surrogate to a String -// currently works, but converting a String to a Buffer (via `new Buffer`, or -// Buffer#write) will replace incomplete surrogates with the unicode -// replacement character. See https://codereview.chromium.org/121173009/ . -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var available = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, 0, available); - this.charReceived += available; + // nothing in the list, definitely empty. + if (list.length === 0) return null; - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } + if (length === 0) ret = null;else if (objectMode) ret = list.shift();else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) ret = list.join('');else if (list.length === 1) ret = list[0];else ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) ret = '';else ret = new Buffer(n); - // remove bytes belonging to the current character from the buffer - buffer = buffer.slice(available, buffer.length); + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + if (stringMode) ret += buf.slice(0, cpy);else buf.copy(ret, c, 0, cpy); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; + if (cpy < buf.length) list[0] = buf.slice(cpy);else list.shift(); - // if there are no more bytes in this buffer, just emit our char - if (buffer.length === 0) { - return charStr; + c += cpy; + } } - break; } - // determine and set charLength / charReceived - this.detectIncompleteChar(buffer); + return ret; +} - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); - end -= this.charReceived; - } +function endReadable(stream) { + var state = stream._readableState; - charStr += buffer.toString(this.encoding, 0, end); + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) throw new Error('endReadable called on non-empty stream'); - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - buffer.copy(this.charBuffer, 0, 0, size); - return charStr.substring(0, end); + if (!state.endEmitted) { + state.ended = true; + processNextTick(endReadableNT, state, stream); } +} - // or just emit the charStr - return charStr; -}; - -// detectIncompleteChar determines if there is an incomplete UTF-8 character at -// the end of the given buffer. If so, it sets this.charLength to the byte -// length that character, and sets this.charReceived to the number of bytes -// that are available for this character. -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; - - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; +function endReadableNT(state, stream) { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } +} - // See http://en.wikipedia.org/wiki/UTF-8#Description +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} +}).call(this,require('_process')) +},{"./_stream_duplex":59,"_process":57,"buffer":44,"core-util-is":45,"events":48,"inherits":51,"isarray":53,"process-nextick-args":56,"string_decoder/":69,"util":41}],62:[function(require,module,exports){ +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } +'use strict'; - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } - } - this.charReceived = i; -}; +module.exports = Transform; -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); +var Duplex = require('./_stream_duplex'); - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ - return res; -}; +util.inherits(Transform, Duplex); -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); -} +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; -function utf16DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 2; - this.charLength = this.charReceived ? 2 : 0; + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = null; } -function base64DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 3; - this.charLength = this.charReceived ? 3 : 0; -} +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; -},{"buffer":43}],65:[function(require,module,exports){ -module.exports = function isBuffer(arg) { - return arg && typeof arg === 'object' - && typeof arg.copy === 'function' - && typeof arg.fill === 'function' - && typeof arg.readUInt8 === 'function'; + var cb = ts.writecb; + + if (!cb) return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (data !== null && data !== undefined) stream.push(data); + + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } } -},{}],66:[function(require,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. -var formatRegExp = /%[sdj%]/g; -exports.format = function(f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); - } - return objects.join(' '); +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + + if (typeof options.flush === 'function') this._flush = options.flush; } - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': return String(args[i++]); - case '%d': return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } - default: - return x; - } + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er) { + done(stream, er); + });else done(stream); }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; - } else { - str += ' ' + inspect(x); - } - } - return str; +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); }; +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function (chunk, encoding, cb) { + throw new Error('not implemented'); +}; -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. -exports.deprecate = function(fn, msg) { - // Allow for deprecating things in the process of starting up. - if (isUndefined(global.process)) { - return function() { - return exports.deprecate(fn, msg).apply(this, arguments); - }; +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); } +}; - if (process.noDeprecation === true) { - return fn; - } +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function (n) { + var ts = this._transformState; - var warned = false; - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); - } else { - console.error(msg); - } - warned = true; - } - return fn.apply(this, arguments); + if (ts.writechunk !== null && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; } - - return deprecated; }; +function done(stream, er) { + if (er) return stream.emit('error', er); -var debugs = {}; -var debugEnviron; -exports.debuglog = function(set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function() { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function() {}; - } - } - return debugs[set]; -}; + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + if (ws.length) throw new Error('calling transform done when ws.length != 0'); -/** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ -/* legacy: obj, showHidden, depth, colors*/ -function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); - } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); + if (ts.transforming) throw new Error('calling transform done when still transforming'); + + return stream.push(null); } -exports.inspect = inspect; +},{"./_stream_duplex":59,"core-util-is":45,"inherits":51}],63:[function(require,module,exports){ +(function (process){ +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. +'use strict'; -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics -inspect.colors = { - 'bold' : [1, 22], - 'italic' : [3, 23], - 'underline' : [4, 24], - 'inverse' : [7, 27], - 'white' : [37, 39], - 'grey' : [90, 39], - 'black' : [30, 39], - 'blue' : [34, 39], - 'cyan' : [36, 39], - 'green' : [32, 39], - 'magenta' : [35, 39], - 'red' : [31, 39], - 'yellow' : [33, 39] -}; +module.exports = Writable; -// Don't use 'blue' not visible on cmd.exe -inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' -}; +/**/ +var processNextTick = require('process-nextick-args'); +/**/ +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/**/ -function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; +/**/ +var Buffer = require('buffer').Buffer; +/**/ - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } -} +Writable.WritableState = WritableState; +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ -function stylizeNoColor(str, styleType) { - return str; -} +/**/ +var internalUtil = { + deprecate: require('util-deprecate') +}; +/**/ +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ -function arrayToHash(array) { - var hash = {}; +var Buffer = require('buffer').Buffer; - array.forEach(function(val, idx) { - hash[val] = true; - }); +util.inherits(Writable, Stream); - return hash; +function nop() {} + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; } +var Duplex; +function WritableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); -function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } + options = options || {}; - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = this.objectMode ? 16 : 16 * 1024; + this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } - } + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; - var base = '', array = false, braces = ['{', '}']; + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; - } + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } + // a flag to see when we're in the middle of a write. + this.writing = false; - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } + // when true all writes will be buffered until .uncork() call + this.corked = 0; - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; - } + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } + // the callback that's passed to _write(chunk,cb) + this.onwrite = function (er) { + onwrite(stream, er); + }; - ctx.seen.push(value); + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function(key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } + // the amount that is being written when _write is called. + this.writelen = 0; - ctx.seen.pop(); + this.bufferedRequest = null; + this.lastBufferedRequest = null; - return reduceToSingleString(output, base, braces); + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; + + // count buffered requests + this.bufferedRequestCount = 0; + + // create the two objects needed to store the corked requests + // they are not a linked list, as no new elements are inserted in there + this.corkedRequestsFree = new CorkedRequest(this); + this.corkedRequestsFree.next = new CorkedRequest(this); } +WritableState.prototype.getBuffer = function writableStateGetBuffer() { + var current = this.bufferedRequest; + var out = []; + while (current) { + out.push(current); + current = current.next; + } + return out; +}; + +(function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function () { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.') + }); + } catch (_) {} +})(); -function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); +var Duplex; +function Writable(options) { + Duplex = Duplex || require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + + if (typeof options.writev === 'function') this._writev = options.writev; } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); + + Stream.call(this); } +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function () { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; -function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; +function writeAfterEnd(stream, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + processNextTick(cb, er); } +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; -function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); - } else { - output.push(''); - } + if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== null && chunk !== undefined && !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + processNextTick(cb, er); + valid = false; } - keys.forEach(function(key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); - } - }); - return output; + return valid; } +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; -function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function(line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } + + if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + + if (typeof cb !== 'function') cb = nop; + + if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); } - return name + ': ' + str; -} + return ret; +}; +Writable.prototype.cork = function () { + var state = this._writableState; -function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function(prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); + state.corked++; +}; - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; +Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); } +}; - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); + this._writableState.defaultEncoding = encoding; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = new Buffer(chunk, encoding); + } + return chunk; } +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. -function isArray(ar) { - return Array.isArray(ar); -} -exports.isArray = isArray; + if (Buffer.isBuffer(chunk)) encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; + state.length += len; -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) state.needDrain = true; -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = new WriteReq(chunk, encoding, cb); + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } -function isNumber(arg) { - return typeof arg === 'number'; + return ret; } -exports.isNumber = isNumber; -function isString(arg) { - return typeof arg === 'string'; +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; } -exports.isString = isString; -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) processNextTick(cb, er);else cb(er); -function isUndefined(arg) { - return arg === void 0; + stream._writableState.errorEmitted = true; + stream.emit('error', er); } -exports.isUndefined = isUndefined; -function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; } -exports.isRegExp = isRegExp; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; -function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; + onwriteStateUpdate(state); -function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state); + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + /**/ + asyncWrite(afterWrite, stream, state, finished, cb); + /**/ + } else { + afterWrite(stream, state, finished, cb); + } + } } -exports.isError = isError; -function isFunction(arg) { - return typeof arg === 'function'; +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); } -exports.isFunction = isFunction; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } } -exports.isPrimitive = isPrimitive; -exports.isBuffer = require('./support/isBuffer'); +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; -function objectToString(o) { - return Object.prototype.toString.call(o); -} + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + var count = 0; + while (entry) { + buffer[count] = entry; + entry = entry.next; + count += 1; + } -function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); -} + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + break; + } + } -var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; + if (entry === null) state.lastBufferedRequest = null; + } -// 26 Feb 16:19:34 -function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); + state.bufferedRequestCount = 0; + state.bufferedRequest = entry; + state.bufferProcessing = false; } - -// log is just a thin wrapper to console.log that prepends a timestamp -exports.log = function() { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('not implemented')); }; +Writable.prototype._writev = null; -/** - * Inherit the prototype methods from one constructor into another. - * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). - * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. - */ -exports.inherits = require('inherits'); - -exports._extend = function(origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; } - return origin; -}; - -function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); -} -}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":65,"_process":51,"inherits":48}],67:[function(require,module,exports){ -/* See LICENSE file for terms of use */ + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); -/* - * Text diff implementation. - * - * This library supports the following APIS: - * JsDiff.diffChars: Character by character diff - * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace - * JsDiff.diffLines: Line based diff - * - * JsDiff.diffCss: Diff targeted at CSS content - * - * These methods are based on the implementation proposed in - * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986). - * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927 - */ -(function(global, undefined) { - var objectPrototypeToString = Object.prototype.toString; + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } - /*istanbul ignore next*/ - function map(arr, mapper, that) { - if (Array.prototype.map) { - return Array.prototype.map.call(arr, mapper, that); - } + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) endWritable(this, state, cb); +}; - var other = new Array(arr.length); +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} - for (var i = 0, n = arr.length; i < n; i++) { - other[i] = mapper.call(that, arr[i], i, arr); - } - return other; - } - function clonePath(path) { - return { newPos: path.newPos, components: path.components.slice(0) }; +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); } - function removeEmpty(array) { - var ret = []; - for (var i = 0; i < array.length; i++) { - if (array[i]) { - ret.push(array[i]); - } +} + +function finishMaybe(stream, state) { + var need = needFinish(state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else { + prefinish(stream, state); } - return ret; } - function escapeHTML(s) { - var n = s; - n = n.replace(/&/g, '&'); - n = n.replace(//g, '>'); - n = n.replace(/"/g, '"'); + return need; +} - return n; +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) processNextTick(cb);else stream.once('finish', cb); } + state.ended = true; + stream.writable = false; +} - // This function handles the presence of circular references by bailing out when encountering an - // object that is already on the "stack" of items being processed. - function canonicalize(obj, stack, replacementStack) { - stack = stack || []; - replacementStack = replacementStack || []; +// It seems a linked list but it is not +// there will be only 2 of these for each stream +function CorkedRequest(state) { + var _this = this; - var i; + this.next = null; + this.entry = null; - for (i = 0; i < stack.length; i += 1) { - if (stack[i] === obj) { - return replacementStack[i]; - } + this.finish = function (err) { + var entry = _this.entry; + _this.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; } - - var canonicalizedObj; - - if ('[object Array]' === objectPrototypeToString.call(obj)) { - stack.push(obj); - canonicalizedObj = new Array(obj.length); - replacementStack.push(canonicalizedObj); - for (i = 0; i < obj.length; i += 1) { - canonicalizedObj[i] = canonicalize(obj[i], stack, replacementStack); - } - stack.pop(); - replacementStack.pop(); - } else if (typeof obj === 'object' && obj !== null) { - stack.push(obj); - canonicalizedObj = {}; - replacementStack.push(canonicalizedObj); - var sortedKeys = [], - key; - for (key in obj) { - sortedKeys.push(key); - } - sortedKeys.sort(); - for (i = 0; i < sortedKeys.length; i += 1) { - key = sortedKeys[i]; - canonicalizedObj[key] = canonicalize(obj[key], stack, replacementStack); - } - stack.pop(); - replacementStack.pop(); + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = _this; } else { - canonicalizedObj = obj; + state.corkedRequestsFree = _this; } - return canonicalizedObj; - } + }; +} +}).call(this,require('_process')) +},{"./_stream_duplex":59,"_process":57,"buffer":44,"core-util-is":45,"events":48,"inherits":51,"process-nextick-args":56,"util-deprecate":71}],64:[function(require,module,exports){ +module.exports = require("./lib/_stream_passthrough.js") - function buildValues(components, newString, oldString, useLongestToken) { - var componentPos = 0, - componentLen = components.length, - newPos = 0, - oldPos = 0; +},{"./lib/_stream_passthrough.js":60}],65:[function(require,module,exports){ +(function (process){ +var Stream = (function (){ + try { + return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify + } catch(_){} +}()); +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = Stream || exports; +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); - for (; componentPos < componentLen; componentPos++) { - var component = components[componentPos]; - if (!component.removed) { - if (!component.added && useLongestToken) { - var value = newString.slice(newPos, newPos + component.count); - value = map(value, function(value, i) { - var oldValue = oldString[oldPos + i]; - return oldValue.length > value.length ? oldValue : value; - }); +if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { + module.exports = Stream; +} - component.value = value.join(''); - } else { - component.value = newString.slice(newPos, newPos + component.count).join(''); - } - newPos += component.count; +}).call(this,require('_process')) +},{"./lib/_stream_duplex.js":59,"./lib/_stream_passthrough.js":60,"./lib/_stream_readable.js":61,"./lib/_stream_transform.js":62,"./lib/_stream_writable.js":63,"_process":57}],66:[function(require,module,exports){ +module.exports = require("./lib/_stream_transform.js") - // Common case - if (!component.added) { - oldPos += component.count; - } - } else { - component.value = oldString.slice(oldPos, oldPos + component.count).join(''); - oldPos += component.count; +},{"./lib/_stream_transform.js":62}],67:[function(require,module,exports){ +module.exports = require("./lib/_stream_writable.js") - // Reverse add and remove so removes are output first to match common convention - // The diffing algorithm is tied to add then remove output and this is the simplest - // route to get the desired output with minimal overhead. - if (componentPos && components[componentPos - 1].added) { - var tmp = components[componentPos - 1]; - components[componentPos - 1] = components[componentPos]; - components[componentPos] = tmp; - } - } - } +},{"./lib/_stream_writable.js":63}],68:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - return components; - } +module.exports = Stream; - function Diff(ignoreWhitespace) { - this.ignoreWhitespace = ignoreWhitespace; - } - Diff.prototype = { - diff: function(oldString, newString, callback) { - var self = this; +var EE = require('events').EventEmitter; +var inherits = require('inherits'); - function done(value) { - if (callback) { - setTimeout(function() { callback(undefined, value); }, 0); - return true; - } else { - return value; - } - } +inherits(Stream, EE); +Stream.Readable = require('readable-stream/readable.js'); +Stream.Writable = require('readable-stream/writable.js'); +Stream.Duplex = require('readable-stream/duplex.js'); +Stream.Transform = require('readable-stream/transform.js'); +Stream.PassThrough = require('readable-stream/passthrough.js'); - // Handle the identity case (this is due to unrolling editLength == 0 - if (newString === oldString) { - return done([{ value: newString }]); - } - if (!newString) { - return done([{ value: oldString, removed: true }]); - } - if (!oldString) { - return done([{ value: newString, added: true }]); - } +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; - newString = this.tokenize(newString); - oldString = this.tokenize(oldString); - var newLen = newString.length, oldLen = oldString.length; - var editLength = 1; - var maxEditLength = newLen + oldLen; - var bestPath = [{ newPos: -1, components: [] }]; - // Seed editLength = 0, i.e. the content starts with the same values - var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0); - if (bestPath[0].newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - // Identity per the equality and tokenizer - return done([{value: newString.join('')}]); - } +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. - // Main worker method. checks all permutations of a given edit length for acceptance. - function execEditLength() { - for (var diagonalPath = -1 * editLength; diagonalPath <= editLength; diagonalPath += 2) { - var basePath; - var addPath = bestPath[diagonalPath - 1], - removePath = bestPath[diagonalPath + 1], - oldPos = (removePath ? removePath.newPos : 0) - diagonalPath; - if (addPath) { - // No one else is going to attempt to use this value, clear it - bestPath[diagonalPath - 1] = undefined; - } +function Stream() { + EE.call(this); +} - var canAdd = addPath && addPath.newPos + 1 < newLen, - canRemove = removePath && 0 <= oldPos && oldPos < oldLen; - if (!canAdd && !canRemove) { - // If this path is a terminal then prune - bestPath[diagonalPath] = undefined; - continue; - } +Stream.prototype.pipe = function(dest, options) { + var source = this; - // Select the diagonal that we want to branch from. We select the prior - // path whose position in the new string is the farthest from the origin - // and does not pass the bounds of the diff graph - if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) { - basePath = clonePath(removePath); - self.pushComponent(basePath.components, undefined, true); - } else { - basePath = addPath; // No need to clone, we've pulled it from the list - basePath.newPos++; - self.pushComponent(basePath.components, true, undefined); - } + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } - oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); + source.on('data', ondata); - // If we have hit the end of both strings, then we are done - if (basePath.newPos + 1 >= newLen && oldPos + 1 >= oldLen) { - return done(buildValues(basePath.components, newString, oldString, self.useLongestToken)); - } else { - // Otherwise track this path as a potential candidate and continue. - bestPath[diagonalPath] = basePath; - } - } + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } - editLength++; - } + dest.on('drain', ondrain); - // Performs the length of edit iteration. Is a bit fugly as this has to support the - // sync and async mode which is never fun. Loops over execEditLength until a value - // is produced. - if (callback) { - (function exec() { - setTimeout(function() { - // This should not happen, but we want to be safe. - /*istanbul ignore next */ - if (editLength > maxEditLength) { - return callback(); - } + // If the 'end' option is not supplied, dest.end() will be called when + // source gets the 'end' or 'close' events. Only dest.end() once. + if (!dest._isStdio && (!options || options.end !== false)) { + source.on('end', onend); + source.on('close', onclose); + } - if (!execEditLength()) { - exec(); - } - }, 0); - }()); - } else { - while (editLength <= maxEditLength) { - var ret = execEditLength(); - if (ret) { - return ret; - } - } - } - }, + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; - pushComponent: function(components, added, removed) { - var last = components[components.length - 1]; - if (last && last.added === added && last.removed === removed) { - // We need to clone here as the component clone operation is just - // as shallow array clone - components[components.length - 1] = {count: last.count + 1, added: added, removed: removed }; - } else { - components.push({count: 1, added: added, removed: removed }); - } - }, - extractCommon: function(basePath, newString, oldString, diagonalPath) { - var newLen = newString.length, - oldLen = oldString.length, - newPos = basePath.newPos, - oldPos = newPos - diagonalPath, + dest.end(); + } - commonCount = 0; - while (newPos + 1 < newLen && oldPos + 1 < oldLen && this.equals(newString[newPos + 1], oldString[oldPos + 1])) { - newPos++; - oldPos++; - commonCount++; - } - if (commonCount) { - basePath.components.push({count: commonCount}); - } + function onclose() { + if (didOnEnd) return; + didOnEnd = true; - basePath.newPos = newPos; - return oldPos; - }, + if (typeof dest.destroy === 'function') dest.destroy(); + } - equals: function(left, right) { - var reWhitespace = /\S/; - return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)); - }, - tokenize: function(value) { - return value.split(''); + // don't leave dangling pipes when there are errors. + function onerror(er) { + cleanup(); + if (EE.listenerCount(this, 'error') === 0) { + throw er; // Unhandled stream error in pipe. } - }; + } - var CharDiff = new Diff(); + source.on('error', onerror); + dest.on('error', onerror); - var WordDiff = new Diff(true); - var WordWithSpaceDiff = new Diff(); - WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) { - return removeEmpty(value.split(/(\s+|\b)/)); - }; + // remove all the event listeners that were added. + function cleanup() { + source.removeListener('data', ondata); + dest.removeListener('drain', ondrain); - var CssDiff = new Diff(true); - CssDiff.tokenize = function(value) { - return removeEmpty(value.split(/([{}:;,]|\s+)/)); - }; + source.removeListener('end', onend); + source.removeListener('close', onclose); - var LineDiff = new Diff(); + source.removeListener('error', onerror); + dest.removeListener('error', onerror); - var TrimmedLineDiff = new Diff(); - TrimmedLineDiff.ignoreTrim = true; + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); - LineDiff.tokenize = TrimmedLineDiff.tokenize = function(value) { - var retLines = [], - lines = value.split(/^/m); - for (var i = 0; i < lines.length; i++) { - var line = lines[i], - lastLine = lines[i - 1], - lastLineLastChar = lastLine && lastLine[lastLine.length - 1]; + dest.removeListener('close', cleanup); + } - // Merge lines that may contain windows new lines - if (line === '\n' && lastLineLastChar === '\r') { - retLines[retLines.length - 1] = retLines[retLines.length - 1].slice(0, -1) + '\r\n'; - } else { - if (this.ignoreTrim) { - line = line.trim(); - // add a newline unless this is the last line. - if (i < lines.length - 1) { - line += '\n'; - } - } - retLines.push(line); - } - } + source.on('end', cleanup); + source.on('close', cleanup); - return retLines; - }; + dest.on('close', cleanup); - var PatchDiff = new Diff(); - PatchDiff.tokenize = function(value) { - var ret = [], - linesAndNewlines = value.split(/(\n|\r\n)/); + dest.emit('pipe', source); - // Ignore the final empty token that occurs if the string ends with a new line - if (!linesAndNewlines[linesAndNewlines.length - 1]) { - linesAndNewlines.pop(); - } + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; - // Merge the content and line separators into single tokens - for (var i = 0; i < linesAndNewlines.length; i++) { - var line = linesAndNewlines[i]; +},{"events":48,"inherits":51,"readable-stream/duplex.js":58,"readable-stream/passthrough.js":64,"readable-stream/readable.js":65,"readable-stream/transform.js":66,"readable-stream/writable.js":67}],69:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. - if (i % 2) { - ret[ret.length - 1] += line; - } else { - ret.push(line); - } - } - return ret; - }; +var Buffer = require('buffer').Buffer; - var SentenceDiff = new Diff(); - SentenceDiff.tokenize = function(value) { - return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/)); - }; +var isBufferEncoding = Buffer.isEncoding + || function(encoding) { + switch (encoding && encoding.toLowerCase()) { + case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; + default: return false; + } + } - var JsonDiff = new Diff(); - // Discriminate between two lines of pretty-printed, serialized JSON where one of them has a - // dangling comma and the other doesn't. Turns out including the dangling comma yields the nicest output: - JsonDiff.useLongestToken = true; - JsonDiff.tokenize = LineDiff.tokenize; - JsonDiff.equals = function(left, right) { - return LineDiff.equals(left.replace(/,([\r\n])/g, '$1'), right.replace(/,([\r\n])/g, '$1')); - }; - var JsDiff = { - Diff: Diff, +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} - diffChars: function(oldStr, newStr, callback) { return CharDiff.diff(oldStr, newStr, callback); }, - diffWords: function(oldStr, newStr, callback) { return WordDiff.diff(oldStr, newStr, callback); }, - diffWordsWithSpace: function(oldStr, newStr, callback) { return WordWithSpaceDiff.diff(oldStr, newStr, callback); }, - diffLines: function(oldStr, newStr, callback) { return LineDiff.diff(oldStr, newStr, callback); }, - diffTrimmedLines: function(oldStr, newStr, callback) { return TrimmedLineDiff.diff(oldStr, newStr, callback); }, +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. CESU-8 is handled as part of the UTF-8 encoding. +// +// @TODO Handling all encodings inside a single object makes it very difficult +// to reason about this code, so it should be split up in the future. +// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code +// points as used by CESU-8. +var StringDecoder = exports.StringDecoder = function(encoding) { + this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); + assertEncoding(encoding); + switch (this.encoding) { + case 'utf8': + // CESU-8 represents each of Surrogate Pair by 3-bytes + this.surrogateSize = 3; + break; + case 'ucs2': + case 'utf16le': + // UTF-16 represents each of Surrogate Pair by 2-bytes + this.surrogateSize = 2; + this.detectIncompleteChar = utf16DetectIncompleteChar; + break; + case 'base64': + // Base-64 stores 3 bytes in 4 chars, and pads the remainder. + this.surrogateSize = 3; + this.detectIncompleteChar = base64DetectIncompleteChar; + break; + default: + this.write = passThroughWrite; + return; + } - diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); }, + // Enough space to store all bytes of a single character. UTF-8 needs 4 + // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). + this.charBuffer = new Buffer(6); + // Number of bytes received for the current incomplete multi-byte character. + this.charReceived = 0; + // Number of bytes expected for the current incomplete multi-byte character. + this.charLength = 0; +}; - diffCss: function(oldStr, newStr, callback) { return CssDiff.diff(oldStr, newStr, callback); }, - diffJson: function(oldObj, newObj, callback) { - return JsonDiff.diff( - typeof oldObj === 'string' ? oldObj : JSON.stringify(canonicalize(oldObj), undefined, ' '), - typeof newObj === 'string' ? newObj : JSON.stringify(canonicalize(newObj), undefined, ' '), - callback - ); - }, - createTwoFilesPatch: function(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader) { - var ret = []; +// write decodes the given buffer and returns it as JS string that is +// guaranteed to not contain any partial multi-byte characters. Any partial +// character found at the end of the buffer is buffered up, and will be +// returned when calling write again with the remaining bytes. +// +// Note: Converting a Buffer containing an orphan surrogate to a String +// currently works, but converting a String to a Buffer (via `new Buffer`, or +// Buffer#write) will replace incomplete surrogates with the unicode +// replacement character. See https://codereview.chromium.org/121173009/ . +StringDecoder.prototype.write = function(buffer) { + var charStr = ''; + // if our last write ended with an incomplete multibyte character + while (this.charLength) { + // determine how many remaining bytes this buffer has to offer for this char + var available = (buffer.length >= this.charLength - this.charReceived) ? + this.charLength - this.charReceived : + buffer.length; - if (oldFileName == newFileName) { - ret.push('Index: ' + oldFileName); - } - ret.push('==================================================================='); - ret.push('--- ' + oldFileName + (typeof oldHeader === 'undefined' ? '' : '\t' + oldHeader)); - ret.push('+++ ' + newFileName + (typeof newHeader === 'undefined' ? '' : '\t' + newHeader)); + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; - var diff = PatchDiff.diff(oldStr, newStr); - diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } - // Formats a given set of lines for printing as context lines in a patch - function contextLines(lines) { - return map(lines, function(entry) { return ' ' + entry; }); - } + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); - // Outputs the no newline at end of file warning if needed - function eofNL(curRange, i, current) { - var last = diff[diff.length - 2], - isLast = i === diff.length - 2, - isLastOfType = i === diff.length - 3 && current.added !== last.added; + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); - // Figure out if this is the last line for the given file and missing NL - if (!(/\n$/.test(current.value)) && (isLast || isLastOfType)) { - curRange.push('\\ No newline at end of file'); - } - } + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + var charCode = charStr.charCodeAt(charStr.length - 1); + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + this.charLength += this.surrogateSize; + charStr = ''; + continue; + } + this.charReceived = this.charLength = 0; - var oldRangeStart = 0, newRangeStart = 0, curRange = [], - oldLine = 1, newLine = 1; - for (var i = 0; i < diff.length; i++) { - var current = diff[i], - lines = current.lines || current.value.replace(/\n$/, '').split('\n'); - current.lines = lines; + // if there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } - if (current.added || current.removed) { - // If we have previous context, start with that - if (!oldRangeStart) { - var prev = diff[i - 1]; - oldRangeStart = oldLine; - newRangeStart = newLine; + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); - if (prev) { - curRange = contextLines(prev.lines.slice(-4)); - oldRangeStart -= curRange.length; - newRangeStart -= curRange.length; - } - } + var end = buffer.length; + if (this.charLength) { + // buffer the incomplete character bytes we got + buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); + end -= this.charReceived; + } - // Output our changes - curRange.push.apply(curRange, map(lines, function(entry) { - return (current.added ? '+' : '-') + entry; - })); - eofNL(curRange, i, current); + charStr += buffer.toString(this.encoding, 0, end); - // Track the updated file position - if (current.added) { - newLine += lines.length; - } else { - oldLine += lines.length; - } - } else { - // Identical context lines. Track line changes - if (oldRangeStart) { - // Close out any changes that have been output (or join overlapping) - if (lines.length <= 8 && i < diff.length - 2) { - // Overlapping - curRange.push.apply(curRange, contextLines(lines)); - } else { - // end the range and output - var contextSize = Math.min(lines.length, 4); - ret.push( - '@@ -' + oldRangeStart + ',' + (oldLine - oldRangeStart + contextSize) - + ' +' + newRangeStart + ',' + (newLine - newRangeStart + contextSize) - + ' @@'); - ret.push.apply(ret, curRange); - ret.push.apply(ret, contextLines(lines.slice(0, contextSize))); - if (lines.length <= 4) { - eofNL(ret, i, current); - } + var end = charStr.length - 1; + var charCode = charStr.charCodeAt(end); + // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character + if (charCode >= 0xD800 && charCode <= 0xDBFF) { + var size = this.surrogateSize; + this.charLength += size; + this.charReceived += size; + this.charBuffer.copy(this.charBuffer, size, 0, size); + buffer.copy(this.charBuffer, 0, 0, size); + return charStr.substring(0, end); + } - oldRangeStart = 0; - newRangeStart = 0; - curRange = []; - } - } - oldLine += lines.length; - newLine += lines.length; - } - } + // or just emit the charStr + return charStr; +}; - return ret.join('\n') + '\n'; - }, +// detectIncompleteChar determines if there is an incomplete UTF-8 character at +// the end of the given buffer. If so, it sets this.charLength to the byte +// length that character, and sets this.charReceived to the number of bytes +// that are available for this character. +StringDecoder.prototype.detectIncompleteChar = function(buffer) { + // determine how many bytes we have to check at the end of this buffer + var i = (buffer.length >= 3) ? 3 : buffer.length; - createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) { - return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader); - }, + // Figure out if one of the last i bytes of our buffer announces an + // incomplete char. + for (; i > 0; i--) { + var c = buffer[buffer.length - i]; - applyPatch: function(oldStr, uniDiff) { - var diffstr = uniDiff.split('\n'), - hunks = [], - i = 0, - remEOFNL = false, - addEOFNL = false; + // See http://en.wikipedia.org/wiki/UTF-8#Description - // Skip to the first change hunk - while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) { - i++; - } + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } - // Parse the unified diff - for (; i < diffstr.length; i++) { - if (diffstr[i][0] === '@') { - var chnukHeader = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/); - hunks.unshift({ - start: chnukHeader[3], - oldlength: +chnukHeader[2], - removed: [], - newlength: chnukHeader[4], - added: [] - }); - } else if (diffstr[i][0] === '+') { - hunks[0].added.push(diffstr[i].substr(1)); - } else if (diffstr[i][0] === '-') { - hunks[0].removed.push(diffstr[i].substr(1)); - } else if (diffstr[i][0] === ' ') { - hunks[0].added.push(diffstr[i].substr(1)); - hunks[0].removed.push(diffstr[i].substr(1)); - } else if (diffstr[i][0] === '\\') { - if (diffstr[i - 1][0] === '+') { - remEOFNL = true; - } else if (diffstr[i - 1][0] === '-') { - addEOFNL = true; - } - } - } + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } - // Apply the diff to the input - var lines = oldStr.split('\n'); - for (i = hunks.length - 1; i >= 0; i--) { - var hunk = hunks[i]; - // Sanity check the input string. Bail if we don't match. - for (var j = 0; j < hunk.oldlength; j++) { - if (lines[hunk.start - 1 + j] !== hunk.removed[j]) { - return false; - } - } - Array.prototype.splice.apply(lines, [hunk.start - 1, hunk.oldlength].concat(hunk.added)); - } + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; - // Handle EOFNL insertion/removal - if (remEOFNL) { - while (!lines[lines.length - 1]) { - lines.pop(); - } - } else if (addEOFNL) { - lines.push(''); +StringDecoder.prototype.end = function(buffer) { + var res = ''; + if (buffer && buffer.length) + res = this.write(buffer); + + if (this.charReceived) { + var cr = this.charReceived; + var buf = this.charBuffer; + var enc = this.encoding; + res += buf.slice(0, cr).toString(enc); + } + + return res; +}; + +function passThroughWrite(buffer) { + return buffer.toString(this.encoding); +} + +function utf16DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 2; + this.charLength = this.charReceived ? 2 : 0; +} + +function base64DetectIncompleteChar(buffer) { + this.charReceived = buffer.length % 3; + this.charLength = this.charReceived ? 3 : 0; +} + +},{"buffer":44}],70:[function(require,module,exports){ + +/** + * Expose `toIsoString`. + */ + +module.exports = toIsoString; + + +/** + * Turn a `date` into an ISO string. + * + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString + * + * @param {Date} date + * @return {String} + */ + +function toIsoString (date) { + return date.getUTCFullYear() + + '-' + pad(date.getUTCMonth() + 1) + + '-' + pad(date.getUTCDate()) + + 'T' + pad(date.getUTCHours()) + + ':' + pad(date.getUTCMinutes()) + + ':' + pad(date.getUTCSeconds()) + + '.' + String((date.getUTCMilliseconds()/1000).toFixed(3)).slice(2, 5) + + 'Z'; +} + + +/** + * Pad a `number` with a ten's place zero. + * + * @param {Number} number + * @return {String} + */ + +function pad (number) { + var n = number.toString(); + return n.length === 1 ? '0' + n : n; +} +},{}],71:[function(require,module,exports){ +(function (global){ + +/** + * Module exports. + */ + +module.exports = deprecate; + +/** + * Mark that a method should not be used. + * Returns a modified function which warns once by default. + * + * If `localStorage.noDeprecation = true` is set, then it is a no-op. + * + * If `localStorage.throwDeprecation = true` is set, then deprecated functions + * will throw an Error when invoked. + * + * If `localStorage.traceDeprecation = true` is set, then deprecated functions + * will invoke `console.trace()` instead of `console.error()`. + * + * @param {Function} fn - the function to deprecate + * @param {String} msg - the string to print to the console when `fn` is invoked + * @returns {Function} a new "deprecated" version of `fn` + * @api public + */ + +function deprecate (fn, msg) { + if (config('noDeprecation')) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (config('throwDeprecation')) { + throw new Error(msg); + } else if (config('traceDeprecation')) { + console.trace(msg); + } else { + console.warn(msg); } - return lines.join('\n'); - }, + warned = true; + } + return fn.apply(this, arguments); + } - convertChangesToXML: function(changes) { - var ret = []; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); - } + return deprecated; +} - ret.push(escapeHTML(change.value)); +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ - if (change.added) { - ret.push(''); - } else if (change.removed) { - ret.push(''); +function config (name) { + // accessing global.localStorage can trigger a DOMException in sandboxed iframes + try { + if (!global.localStorage) return false; + } catch (_) { + return false; + } + var val = global.localStorage[name]; + if (null == val) return false; + return String(val).toLowerCase() === 'true'; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],72:[function(require,module,exports){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +},{}],73:[function(require,module,exports){ +(function (process,global){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); } - return ret.join(''); - }, + warned = true; + } + return fn.apply(this, arguments); + } - // See: http://code.google.com/p/google-diff-match-patch/wiki/API - convertChangesToDMP: function(changes) { - var ret = [], - change, - operation; - for (var i = 0; i < changes.length; i++) { - change = changes[i]; - if (change.added) { - operation = 1; - } else if (change.removed) { - operation = -1; - } else { - operation = 0; - } + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; - ret.push([operation, change.value]); - } - return ret; - }, - canonicalize: canonicalize - }; +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; - /*istanbul ignore next */ - /*global module */ - if (typeof module !== 'undefined' && module.exports) { - module.exports = JsDiff; - } else if (typeof define === 'function' && define.amd) { - /*global define */ - define([], function() { return JsDiff; }); - } else if (typeof global.JsDiff === 'undefined') { - global.JsDiff = JsDiff; + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; } -}(this)); - -},{}],68:[function(require,module,exports){ -'use strict'; - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; +} -module.exports = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - return str.replace(matchOperatorsRe, '\\$&'); -}; +function stylizeNoColor(str, styleType) { + return str; +} -},{}],69:[function(require,module,exports){ -(function (process){ -// Growl - Copyright TJ Holowaychuk (MIT Licensed) -/** - * Module dependencies. - */ +function arrayToHash(array) { + var hash = {}; -var exec = require('child_process').exec - , fs = require('fs') - , path = require('path') - , exists = fs.existsSync || path.existsSync - , os = require('os') - , quote = JSON.stringify - , cmd; + array.forEach(function(val, idx) { + hash[val] = true; + }); -function which(name) { - var paths = process.env.PATH.split(':'); - var loc; - - for (var i = 0, len = paths.length; i < len; ++i) { - loc = path.join(paths[i], name); - if (exists(loc)) return loc; - } + return hash; } -switch(os.type()) { - case 'Darwin': - if (which('terminal-notifier')) { - cmd = { - type: "Darwin-NotificationCenter" - , pkg: "terminal-notifier" - , msg: '-message' - , title: '-title' - , subtitle: '-subtitle' - , priority: { - cmd: '-execute' - , range: [] - } - }; - } else { - cmd = { - type: "Darwin-Growl" - , pkg: "growlnotify" - , msg: '-m' - , sticky: '--sticky' - , priority: { - cmd: '--priority' - , range: [ - -2 - , -1 - , 0 - , 1 - , 2 - , "Very Low" - , "Moderate" - , "Normal" - , "High" - , "Emergency" - ] - } - }; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); } - break; - case 'Linux': - cmd = { - type: "Linux" - , pkg: "notify-send" - , msg: '' - , sticky: '-t 0' - , icon: '-i' - , priority: { - cmd: '-u' - , range: [ - "low" - , "normal" - , "critical" - ] - } - }; - break; - case 'Windows_NT': - cmd = { - type: "Windows" - , pkg: "growlnotify" - , msg: '' - , sticky: '/s:true' - , title: '/t:' - , icon: '/i:' - , priority: { - cmd: '/p:' - , range: [ - -2 - , -1 - , 0 - , 1 - , 2 - ] - } - }; - break; -} + return ret; + } -/** - * Expose `growl`. - */ + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } -exports = module.exports = growl; + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); -/** - * Node-growl version. - */ + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } -exports.version = '1.4.1' + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } -/** - * Send growl notification _msg_ with _options_. - * - * Options: - * - * - title Notification title - * - sticky Make the notification stick (defaults to false) - * - priority Specify an int or named key (default is 0) - * - name Application name (defaults to growlnotify) - * - image - * - path to an icon sets --iconpath - * - path to an image sets --image - * - capitalized word sets --appIcon - * - filename uses extname as --icon - * - otherwise treated as --icon - * - * Examples: - * - * growl('New email') - * growl('5 new emails', { title: 'Thunderbird' }) - * growl('Email sent', function(){ - * // ... notification sent - * }) - * - * @param {string} msg - * @param {object} options - * @param {function} fn - * @api public - */ + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } -function growl(msg, options, fn) { - var image - , args - , options = options || {} - , fn = fn || function(){}; + var base = '', array = false, braces = ['{', '}']; - // noop - if (!cmd) return fn(new Error('growl not supported on this platform')); - args = [cmd.pkg]; + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } - // image - if (image = options.image) { - switch(cmd.type) { - case 'Darwin-Growl': - var flag, ext = path.extname(image).substr(1) - flag = flag || ext == 'icns' && 'iconpath' - flag = flag || /^[A-Z]/.test(image) && 'appIcon' - flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' - flag = flag || ext && (image = ext) && 'icon' - flag = flag || 'icon' - args.push('--' + flag, quote(image)) - break; - case 'Linux': - args.push(cmd.icon, quote(image)); - // libnotify defaults to sticky, set a hint for transient notifications - if (!options.sticky) args.push('--hint=int:transient:1'); - break; - case 'Windows': - args.push(cmd.icon + quote(image)); - break; - } + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; } - // sticky - if (options.sticky) args.push(cmd.sticky); + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } - // priority - if (options.priority) { - var priority = options.priority + ''; - var checkindexOf = cmd.priority.range.indexOf(priority); - if (~cmd.priority.range.indexOf(priority)) { - args.push(cmd.priority, options.priority); - } + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); } - // name - if (options.name && cmd.type === "Darwin-Growl") { - args.push('--name', options.name); + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); } - switch(cmd.type) { - case 'Darwin-Growl': - args.push(cmd.msg); - args.push(quote(msg)); - if (options.title) args.push(quote(options.title)); - break; - case 'Darwin-NotificationCenter': - args.push(cmd.msg); - args.push(quote(msg)); - if (options.title) { - args.push(cmd.title); - args.push(quote(options.title)); - } - if (options.subtitle) { - args.push(cmd.subtitle); - args.push(quote(options.subtitle)); - } - break; - case 'Darwin-Growl': - args.push(cmd.msg); - args.push(quote(msg)); - if (options.title) args.push(quote(options.title)); - break; - case 'Linux': - if (options.title) { - args.push(quote(options.title)); - args.push(cmd.msg); - args.push(quote(msg)); - } else { - args.push(quote(msg)); - } - break; - case 'Windows': - args.push(quote(msg)); - if (options.title) args.push(cmd.title + quote(options.title)); - break; + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; } - // execute - exec(args.join(' '), fn); -}; + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } -}).call(this,require('_process')) -},{"_process":51,"child_process":41,"fs":41,"os":50,"path":41}],70:[function(require,module,exports){ -(function (process){ -var path = require('path'); -var fs = require('fs'); -var _0777 = parseInt('0777', 8); + ctx.seen.push(value); -module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } -function mkdirP (p, opts, f, made) { - if (typeof opts === 'function') { - f = opts; - opts = {}; - } - else if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; - } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); - } - if (!made) made = null; - - var cb = f || function () {}; - p = path.resolve(p); - - xfs.mkdir(p, mode, function (er) { - if (!er) { - made = made || p; - return cb(null, made); - } - switch (er.code) { - case 'ENOENT': - mkdirP(path.dirname(p), opts, function (er, made) { - if (er) cb(er, made); - else mkdirP(p, opts, cb, made); - }); - break; + ctx.seen.pop(); - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - xfs.stat(p, function (er2, stat) { - // if the stat fails, then that's super weird. - // let the original error be the failure reason. - if (er2 || !stat.isDirectory()) cb(er, made) - else cb(null, made); - }); - break; - } - }); + return reduceToSingleString(output, base, braces); } -mkdirP.sync = function sync (p, opts, made) { - if (!opts || typeof opts !== 'object') { - opts = { mode: opts }; + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); } - - var mode = opts.mode; - var xfs = opts.fs || fs; - - if (mode === undefined) { - mode = _0777 & (~process.umask()); + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); } - if (!made) made = null; + }); + return output; +} - p = path.resolve(p); - try { - xfs.mkdirSync(p, mode); - made = made || p; +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); } - catch (err0) { - switch (err0.code) { - case 'ENOENT' : - made = sync(path.dirname(p), opts, made); - sync(p, opts, made); - break; - - // In the case of any other error, just see if there's a dir - // there already. If so, then hooray! If not, then something - // is borked. - default: - var stat; - try { - stat = xfs.statSync(p); - } - catch (err1) { - throw err0; - } - if (!stat.isDirectory()) throw err0; - break; + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); } + } + + return name + ': ' + str; +} - return made; -}; -}).call(this,require('_process')) -},{"_process":51,"fs":41,"path":41}],71:[function(require,module,exports){ -(function (process,global){ -/** - * Shim process.stdout. - */ +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); -process.stdout = require('browser-stdout')(); + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } -var Mocha = require('../'); + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} -/** - * Create a Mocha instance. - * - * @return {undefined} - */ -var mocha = new Mocha({ reporter: 'html' }); +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; -/** - * Save timer references to avoid Sinon interfering (see GH-237). - */ +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; -var Date = global.Date; -var setTimeout = global.setTimeout; -var setInterval = global.setInterval; -var clearTimeout = global.clearTimeout; -var clearInterval = global.clearInterval; +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; -var uncaughtExceptionHandlers = []; +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; -var originalOnerrorHandler = global.onerror; +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; -/** - * Remove uncaughtException listener. - * Revert to original onerror handler if previously defined. - */ +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; -process.removeListener = function(e, fn){ - if ('uncaughtException' == e) { - if (originalOnerrorHandler) { - global.onerror = originalOnerrorHandler; - } else { - global.onerror = function() {}; - } - var i = Mocha.utils.indexOf(uncaughtExceptionHandlers, fn); - if (i != -1) { uncaughtExceptionHandlers.splice(i, 1); } - } -}; +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; -/** - * Implements uncaughtException listener. - */ +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; -process.on = function(e, fn){ - if ('uncaughtException' == e) { - global.onerror = function(err, url, line){ - fn(new Error(err + ' (' + url + ':' + line + ')')); - return !mocha.allowUncaught; - }; - uncaughtExceptionHandlers.push(fn); - } -}; +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; -// The BDD UI is registered by default, but no UI will be functional in the -// browser without an explicit call to the overridden `mocha.ui` (see below). -// Ensure that this default UI does not expose its methods to the global scope. -mocha.suite.removeAllListeners('pre-require'); +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; -var immediateQueue = [] - , immediateTimeout; +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; -function timeslice() { - var immediateStart = new Date().getTime(); - while (immediateQueue.length && (new Date().getTime() - immediateStart) < 100) { - immediateQueue.shift()(); - } - if (immediateQueue.length) { - immediateTimeout = setTimeout(timeslice, 0); - } else { - immediateTimeout = null; - } +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); } +exports.isError = isError; -/** - * High-performance override of Runner.immediately. - */ +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; -Mocha.Runner.immediately = function(callback) { - immediateQueue.push(callback); - if (!immediateTimeout) { - immediateTimeout = setTimeout(timeslice, 0); - } -}; +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; -/** - * Function to allow assertion libraries to throw errors directly into mocha. - * This is useful when running tests in a browser because window.onerror will - * only receive the 'message' attribute of the Error. - */ -mocha.throwError = function(err) { - Mocha.utils.forEach(uncaughtExceptionHandlers, function (fn) { - fn(err); - }); - throw err; -}; +exports.isBuffer = require('./support/isBuffer'); -/** - * Override ui to ensure that the ui functions are initialized. - * Normally this would happen in Mocha.prototype.loadFiles. - */ +function objectToString(o) { + return Object.prototype.toString.call(o); +} -mocha.ui = function(ui){ - Mocha.prototype.ui.call(this, ui); - this.suite.emit('pre-require', global, null, this); - return this; -}; -/** - * Setup mocha with the given setting options. - */ +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} -mocha.setup = function(opts){ - if ('string' == typeof opts) opts = { ui: opts }; - for (var opt in opts) this[opt](opts[opt]); - return this; -}; -/** - * Run mocha, returning the Runner. - */ +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; -mocha.run = function(fn){ - var options = mocha.options; - mocha.globals('location'); +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} - var query = Mocha.utils.parseQuery(global.location.search || ''); - if (query.grep) mocha.grep(new RegExp(query.grep)); - if (query.fgrep) mocha.grep(query.fgrep); - if (query.invert) mocha.invert(); - return Mocha.prototype.run.call(mocha, function(err){ - // The DOM Document is not available in Web Workers. - var document = global.document; - if (document && document.getElementById('mocha') && options.noHighlighting !== true) { - Mocha.utils.highlightTags('code'); - } - if (fn) fn(err); - }); +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); }; + /** - * Expose the process shim. - * https://github.com/mochajs/mocha/pull/916 + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. */ +exports.inherits = require('inherits'); -Mocha.process = process; +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; -/** - * Expose mocha. - */ + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; -global.Mocha = Mocha; -global.mocha = mocha; +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../":1,"_process":51,"browser-stdout":40}]},{},[71]); +},{"./support/isBuffer":72,"_process":57,"inherits":51}]},{},[1]); diff --git a/package.json b/package.json index 49b780cc18..b88346af6a 100644 --- a/package.json +++ b/package.json @@ -250,7 +250,8 @@ "Jordan Sexton ", "Jussi Virtanen ", "Katie Gengler ", - "Kazuhito Hokamura " + "Kazuhito Hokamura ", + "Scott Santucci " ], "license": "MIT", "repository": { @@ -266,7 +267,7 @@ "node": ">= 0.8.x" }, "scripts": { - "test": "make test-all" + "test": "make test" }, "dependencies": { "commander": "2.3.0", @@ -281,11 +282,22 @@ }, "devDependencies": { "browser-stdout": "^1.2.0", - "browserify": "10.2.4", + "browserify": "^13.0.0", "coffee-script": "~1.8.0", "eslint": "^1.2.1", + "expect.js": "^0.3.1", + "karma": "^0.13.22", + "karma-browserify": "^5.0.5", + "karma-expect": "^1.1.2", + "karma-no-mocha": "^2.0.0", + "karma-phantomjs-launcher": "^0.2.3", + "karma-sauce-launcher": "^1.0.0", + "karma-spec-reporter": "0.0.26", + "phantomjs": "1.9.8", "should": "~8.0.0", - "through2": "~0.6.5" + "through2": "~0.6.5", + "to-iso-string": "0.0.2", + "watchify": "^3.7.0" }, "files": [ "bin", @@ -299,7 +311,8 @@ "browser": { "debug": "./lib/browser/debug.js", "events": "./lib/browser/events.js", - "tty": "./lib/browser/tty.js" + "tty": "./lib/browser/tty.js", + "./index.js": "./browser-entry.js" }, "licenses": [ { diff --git a/scripts/ensure-compatible-npm.sh b/scripts/ensure-compatible-npm.sh deleted file mode 100755 index 9ae26c1ac0..0000000000 --- a/scripts/ensure-compatible-npm.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env sh - -set -o nounset -set -o errexit - -npm install semver -if node -e "process.exit(require('semver').lt(process.argv[1], '1.3.7') ? 0 : 1)" $(npm -v); then - # make sure dependencies install with provided npm version - npm install --production - npm install -g npm@2 - npm install -g npm -fi -npm uninstall semver diff --git a/scripts/upgrade-npm.js b/scripts/upgrade-npm.js new file mode 100644 index 0000000000..2e8be81e0a --- /dev/null +++ b/scripts/upgrade-npm.js @@ -0,0 +1,21 @@ +#!/usr/bin/env node + +/** + * This upgrades npm on Travis when using Node.js 0.8x + */ + +if (process.env.TRAVIS_NODE_VERSION === '0.8') { + var exec = require('child_process').exec; + // ensure *dependencies* can be installed using provided npm + exec('npm install --production', function (err) { + if (err) { + throw new Error(err); + } + exec('npm install --global npm@2', function (err) { + if (err) { + throw new Error(err); + } + console.log('Upgraded to npm@2'); + }); + }); +} diff --git a/test/acceptance/context.js b/test/acceptance/context.js index 47c2db7083..69dea139c9 100644 --- a/test/acceptance/context.js +++ b/test/acceptance/context.js @@ -9,18 +9,18 @@ describe('Context', function(){ }) it('should work', function(){ - this.calls.should.eql(['before', 'before two']); + expect(this.calls).to.eql(['before', 'before two']); this.calls.push('test'); }) after(function(){ - this.calls.should.eql(['before', 'before two', 'test']); + expect(this.calls).to.eql(['before', 'before two', 'test']); this.calls.push('after two'); }) }) after(function(){ - this.calls.should.eql(['before', 'before two', 'test', 'after two']); + expect(this.calls).to.eql(['before', 'before two', 'test', 'after two']); }) }) @@ -36,7 +36,7 @@ describe('Context Siblings', function(){ }) it('should work', function(){ - this.hiddenFromSibling.should.eql('This should be hidden') + expect(this.hiddenFromSibling).to.eql('This should be hidden') }) }) @@ -46,27 +46,27 @@ describe('Context Siblings', function(){ }) it('should not have value set within a sibling describe', function(){ - 'This should be hidden'.should.not.eql(this.hiddenFromSibling); + expect('This should be hidden').not.to.eql(this.hiddenFromSibling); this.visibleFromTestSibling = 'Visible from test sibling'; }) it('should allow test siblings to modify shared context', function(){ - 'Visible from test sibling'.should.eql(this.visibleFromTestSibling); + expect('Visible from test sibling').to.eql(this.visibleFromTestSibling); }) it('should have reset this.calls before describe', function(){ - this.calls.should.eql(['before', 'before sibling']); + expect(this.calls).to.eql(['before', 'before sibling']); }) }) after(function(){ - this.calls.should.eql(['before', 'before sibling']); + expect(this.calls).to.eql(['before', 'before sibling']); }) }) describe('timeout()', function(){ it('should return the timeout', function(){ - this.timeout().should.equal(200); + expect(this.timeout()).to.equal(200); }); }); diff --git a/test/acceptance/http.js b/test/acceptance/http.js index 1dfa9146a4..43b8588508 100644 --- a/test/acceptance/http.js +++ b/test/acceptance/http.js @@ -9,7 +9,7 @@ server.listen(8888); describe('http', function(){ it('should provide an example', function(done){ http.get({ path: '/', port: 8888 }, function(res){ - res.should.have.property('statusCode', 200); + expect(res).to.have.property('statusCode', 200); done(); }) }) diff --git a/test/acceptance/interfaces/bdd.js b/test/acceptance/interfaces/bdd.js index bea1db2295..ba444c8f7f 100644 --- a/test/acceptance/interfaces/bdd.js +++ b/test/acceptance/interfaces/bdd.js @@ -1,34 +1,32 @@ -describe('Array', function(){ - describe('#indexOf()', function(){ - it('should return -1 when the value is not present', function(){ - [1,2,3].indexOf(5).should.equal(-1); - [1,2,3].indexOf(0).should.equal(-1); +describe('integer primitives', function(){ + describe('arithmetic', function(){ + it('should add', function(){ + expect(1 + 1).to.equal(2); + expect(2 + 2).to.equal(4); }) - it('should return the correct index when the value is present', function(){ - [1,2,3].indexOf(1).should.equal(0); - [1,2,3].indexOf(2).should.equal(1); - [1,2,3].indexOf(3).should.equal(2); + it('should subtract', function(){ + expect(1 - 1).to.equal(0); + expect(2 - 1).to.equal(1); }) }) }) -describe('Array', function(){ - describe('#pop()', function(){ - it('should remove and return the last value', function(){ - var arr = [1,2,3]; - arr.pop().should.equal(3); - arr.should.eql([1,2]); +describe('integer primitives', function(){ + describe('arithmetic is not', function(){ + it('should add', function(){ + expect(1 + 1).not.to.equal(3); + expect(2 + 2).not.to.equal(5); }) }) }) -context('Array', function(){ +context('test suite', function(){ beforeEach(function(){ - this.arr = [1,2,3]; + this.number = 5; }) - specify('has a length property', function(){ - this.arr.length.should.equal(3); + specify('share a property', function(){ + expect(this.number).to.equal(5); }) }) diff --git a/test/acceptance/interfaces/exports.js b/test/acceptance/interfaces/exports.js index 38093d50ea..08db71200b 100644 --- a/test/acceptance/interfaces/exports.js +++ b/test/acceptance/interfaces/exports.js @@ -7,7 +7,7 @@ exports.Array = { after: function(){ calls.push('after'); - calls.should.eql([ + expect(calls).to.eql([ 'before' , 'before each' , 'one' @@ -29,15 +29,15 @@ exports.Array = { 'should return -1 when the value is not present': function(){ calls.push('one'); - [1,2,3].indexOf(5).should.equal(-1); - [1,2,3].indexOf(0).should.equal(-1); + expect([1,2,3].indexOf(5)).to.equal(-1); + expect([1,2,3].indexOf(0)).to.equal(-1); }, 'should return the correct index when the value is present': function(){ calls.push('two'); - [1,2,3].indexOf(1).should.equal(0); - [1,2,3].indexOf(2).should.equal(1); - [1,2,3].indexOf(3).should.equal(2); + expect([1,2,3].indexOf(1)).to.equal(0); + expect([1,2,3].indexOf(2)).to.equal(1); + expect([1,2,3].indexOf(3)).to.equal(2); } } }; diff --git a/test/acceptance/interfaces/qunit.js b/test/acceptance/interfaces/qunit.js index 48aa21d602..d452e769c5 100644 --- a/test/acceptance/interfaces/qunit.js +++ b/test/acceptance/interfaces/qunit.js @@ -2,18 +2,18 @@ function ok(expr, msg) { if (!expr) throw new Error(msg); } -suite('Array'); +suite('integer primitives'); -test('#length', function(){ - var arr = [1,2,3]; - ok(arr.length == 3); +test('should add', function(){ + var number = 2 + 2; + ok(number == 4); }); -test('#indexOf()', function(){ - var arr = [1,2,3]; - ok(arr.indexOf(1) == 0); - ok(arr.indexOf(2) == 1); - ok(arr.indexOf(3) == 2); +test('should decrement', function(){ + var number = 3; + ok(--number == 2); + ok(--number == 1); + ok(--number == 0); }); suite('String'); diff --git a/test/acceptance/interfaces/tdd.js b/test/acceptance/interfaces/tdd.js index 1c6885ed42..7ad079e36d 100644 --- a/test/acceptance/interfaces/tdd.js +++ b/test/acceptance/interfaces/tdd.js @@ -1,40 +1,39 @@ -suite('Array', function(){ - suite('#indexOf()', function(){ - var initialValue = 32; +suite('integer primitives', function(){ + suite('arithmetic', function(){ + var initialValue = 41; suiteSetup(function(done){ - initialValue.should.eql(32); - initialValue = 42; + expect(initialValue).to.eql(41); + initialValue += 1; done(); }); - test('should return -1 when the value is not present', function(){ - initialValue.should.eql(42); - [1,2,3].indexOf(5).should.equal(-1); - [1,2,3].indexOf(0).should.equal(-1); + test('should add', function(){ + expect(initialValue).to.eql(42); + expect(1 + 1).to.equal(2); + expect(2 + 2).to.equal(4); }); - test('should return the correct index when the value is present', function(){ - initialValue.should.eql(42); - [1,2,3].indexOf(1).should.equal(0); - [1,2,3].indexOf(2).should.equal(1); - [1,2,3].indexOf(3).should.equal(2); + test('should subtract', function(){ + expect(initialValue).to.eql(42); + expect(1 - 1).to.equal(0); + expect(2 - 1).to.equal(1); }); test.skip('should skip this test', function(){ var zero = 0; - zero.should.equal(1, 'this test should have been skipped'); + expect(zero).to.equal(1, 'this test should have been skipped'); }); suite.skip('should skip this suite', function(){ test('should skip this test', function(){ var zero = 0; - zero.should.equal(1, 'this test should have been skipped'); + expect(zero).to.equal(1, 'this test should have been skipped'); }); }); suiteTeardown(function(done){ - initialValue.should.eql(42); + expect(initialValue).to.eql(42); done(); }); }); diff --git a/test/acceptance/lookup-files.js b/test/acceptance/lookup-files.js new file mode 100644 index 0000000000..504d23aab1 --- /dev/null +++ b/test/acceptance/lookup-files.js @@ -0,0 +1,56 @@ +var utils = require('../../lib/utils'); + +describe('lookupFiles', function() { + var fs = require('fs'), path = require('path'), existsSync = fs.existsSync || + path.existsSync; + + beforeEach(function() { + fs.writeFileSync('/tmp/mocha-utils.js', 'yippy skippy ying yang yow'); + fs.symlinkSync('/tmp/mocha-utils.js', '/tmp/mocha-utils-link.js'); + }); + + it('should not choke on symlinks', function() { + expect(utils.lookupFiles('/tmp', ['js'], false)) + .to + .contain('/tmp/mocha-utils-link.js') + .and + .contain('/tmp/mocha-utils.js') + .and + .have + .length(2); + expect(existsSync('/tmp/mocha-utils-link.js')) + .to + .be(true); + fs.renameSync('/tmp/mocha-utils.js', '/tmp/bob'); + expect(existsSync('/tmp/mocha-utils-link.js')) + .to + .be(false); + expect(utils.lookupFiles('/tmp', ['js'], false)) + .to + .eql([]); + }); + + it('should accept a glob "path" value', function() { + expect(utils.lookupFiles('/tmp/mocha-utils*', ['js'], false)) + .to + .contain('/tmp/mocha-utils-link.js') + .and + .contain('/tmp/mocha-utils.js') + .and + .have + .length(2); + }); + + afterEach(function() { + [ + '/tmp/mocha-utils.js', + '/tmp/mocha-utils-link.js', + '/tmp/bob' + ].forEach(function(path) { + try { + fs.unlinkSync(path); + } catch (ignored) { + } + }); + }); +}); diff --git a/test/acceptance/misc/only/bdd.js b/test/acceptance/misc/only/bdd.js index ff14dcdfe3..bb05ad9792 100644 --- a/test/acceptance/misc/only/bdd.js +++ b/test/acceptance/misc/only/bdd.js @@ -1,14 +1,14 @@ describe('should only run .only test in this bdd suite', function() { it('should not run this test', function() { var zero = 0; - zero.should.equal(1, 'this test should have been skipped'); + expect(zero).to.equal(1, 'this test should have been skipped'); }); it.only('should run this test', function() { var zero = 0; - zero.should.equal(0, 'this .only test should run'); + expect(zero).to.equal(0, 'this .only test should run'); }); it('should run this test, not (includes the title of the .only test)', function() { var zero = 0; - zero.should.equal(1, 'this test should have been skipped'); + expect(zero).to.equal(1, 'this test should have been skipped'); }); }); diff --git a/test/acceptance/misc/only/tdd.js b/test/acceptance/misc/only/tdd.js index cb6429a3d6..306d06a9f9 100644 --- a/test/acceptance/misc/only/tdd.js +++ b/test/acceptance/misc/only/tdd.js @@ -1,14 +1,14 @@ suite('should only run .only test in this tdd suite', function() { test('should not run this test', function() { var zero = 0; - zero.should.equal(1, 'this test should have been skipped'); + expect(zero).to.equal(1, 'this test should have been skipped'); }); test.only('should run this test', function() { var zero = 0; - zero.should.equal(0, 'this .only test should run'); + expect(zero).to.equal(0, 'this .only test should run'); }); test('should run this test, not (includes the title of the .only test)', function() { var zero = 0; - zero.should.equal(1, 'this test should have been skipped'); + expect(zero).to.equal(1, 'this test should have been skipped'); }); }); diff --git a/test/acceptance/require/require.js b/test/acceptance/require/require.js index 20f3e6d6ef..22570e62ff 100644 --- a/test/acceptance/require/require.js +++ b/test/acceptance/require/require.js @@ -1,9 +1,9 @@ describe('require test', function(){ it('should require args in order', function(){ var req = global.required; - req.indexOf('a.js').should.equal(0); - req.indexOf('b.coffee').should.equal(1); - req.indexOf('c.js').should.equal(2); - req.indexOf('d.coffee').should.equal(3); + expect(req.indexOf('a.js')).to.equal(0); + expect(req.indexOf('b.coffee')).to.equal(1); + expect(req.indexOf('c.js')).to.equal(2); + expect(req.indexOf('d.coffee')).to.equal(3); }) }); diff --git a/test/acceptance/root.js b/test/acceptance/root.js index 17738302da..037e6a328a 100644 --- a/test/acceptance/root.js +++ b/test/acceptance/root.js @@ -6,6 +6,6 @@ before(function(){ describe('root', function(){ it('should be a valid suite', function(){ - calls.should.eql(['before']); + expect(calls).to.eql(['before']); }) }) diff --git a/test/acceptance/test.coffee b/test/acceptance/test.coffee index 8260940a1e..b8e309f515 100644 --- a/test/acceptance/test.coffee +++ b/test/acceptance/test.coffee @@ -3,4 +3,4 @@ obj = foo: 'bar' describe 'coffeescript', -> it 'should work', -> - obj.should.eql foo: 'bar' + expect(obj).to.eql foo: 'bar' diff --git a/test/acceptance/throw.js b/test/acceptance/throw.js index ac74f22c4a..1016a19efe 100644 --- a/test/acceptance/throw.js +++ b/test/acceptance/throw.js @@ -1,7 +1,6 @@ -var mocha = require('../../') - , Suite = mocha.Suite - , Runner = mocha.Runner - , Test = mocha.Test; +var Suite = require('../../lib/suite'); +var Test = require('../../lib/test'); +var Runner = require('../../lib/runner'); describe('a test that throws', function () { var suite, runner; @@ -10,9 +9,7 @@ describe('a test that throws', function () { suite = new Suite(null, 'root'); runner = new Runner(suite); }) - - this.timeout(50); - + describe('undefined', function (){ it('should not pass if throwing sync and test is sync', function(done) { var test = new Test('im sync and throw undefined sync', function(){ @@ -21,8 +18,8 @@ describe('a test that throws', function () { suite.addTest(test); runner = new Runner(suite); runner.on('end', function(){ - runner.failures.should.equal(1); - test.state.should.equal('failed'); + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); done(); }); runner.run(); @@ -36,8 +33,8 @@ describe('a test that throws', function () { suite.addTest(test); runner = new Runner(suite); runner.on('end', function(){ - runner.failures.should.equal(1); - test.state.should.equal('failed'); + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); done(); }); runner.run(); @@ -53,8 +50,8 @@ describe('a test that throws', function () { suite.addTest(test); runner = new Runner(suite); runner.on('end', function(){ - runner.failures.should.equal(1); - test.state.should.equal('failed'); + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); done(); }); runner.run(); @@ -69,8 +66,8 @@ describe('a test that throws', function () { suite.addTest(test); runner = new Runner(suite); runner.on('end', function(){ - runner.failures.should.equal(1); - test.state.should.equal('failed'); + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); done(); }); runner.run(); @@ -84,8 +81,8 @@ describe('a test that throws', function () { suite.addTest(test); runner = new Runner(suite); runner.on('end', function(){ - runner.failures.should.equal(1); - test.state.should.equal('failed'); + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); done(); }); runner.run(); @@ -101,11 +98,11 @@ describe('a test that throws', function () { suite.addTest(test); runner = new Runner(suite); runner.on('end', function(){ - runner.failures.should.equal(1); - test.state.should.equal('failed'); + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); done(); }); runner.run(); }) }) -}) \ No newline at end of file +}) diff --git a/test/acceptance/utils.js b/test/acceptance/utils.js index 2028d4870b..366d2d8579 100644 --- a/test/acceptance/utils.js +++ b/test/acceptance/utils.js @@ -1,4 +1,5 @@ var utils = require('../../lib/utils'); +var toISOString = require('to-iso-string'); describe('lib/utils', function () { describe('clean', function () { @@ -8,7 +9,7 @@ describe('lib/utils', function () { , " var a = 1;" , "}" ].join("\n"); - utils.clean(fn).should.equal("var a = 1;"); + expect(utils.clean(fn)).to.equal("var a = 1;"); }); it("should format a multi line test indented with spaces", function () { @@ -18,7 +19,7 @@ describe('lib/utils', function () { , " var b = 2;" // this one has more spaces , " var c = 3; }" ].join("\n"); - utils.clean(fn).should.equal("var a = 1;\n var b = 2;\nvar c = 3;"); + expect(utils.clean(fn)).to.equal("var a = 1;\n var b = 2;\nvar c = 3;"); }); it("should format a multi line test indented with tabs", function () { @@ -29,7 +30,7 @@ describe('lib/utils', function () { , "\t}" , "}" ].join("\n"); - utils.clean(fn).should.equal("if (true) {\n\tvar a = 1;\n}"); + expect(utils.clean(fn)).to.equal("if (true) {\n\tvar a = 1;\n}"); }); it("should format functions saved in windows style - spaces", function () { @@ -40,7 +41,7 @@ describe('lib/utils', function () { , " } while (false);" , ' }' ].join("\r\n"); - utils.clean(fn).should.equal('do {\n "nothing";\n} while (false);'); + expect(utils.clean(fn)).to.equal('do {\n "nothing";\n} while (false);'); }); it("should format functions saved in windows style - tabs", function () { @@ -53,7 +54,7 @@ describe('lib/utils', function () { , "\t}" , "}" ].join("\r\n"); - utils.clean(fn).should.equal("if (false) {\n\tvar json = {\n\t\tone : 1\n\t};\n}"); + expect(utils.clean(fn)).to.equal("if (false) {\n\tvar json = {\n\t\tone : 1\n\t};\n}"); }); it("should format es6 arrow functions", function () { @@ -62,12 +63,12 @@ describe('lib/utils', function () { " var a = 1;", "}" ].join("\n"); - utils.clean(fn).should.equal("var a = 1;"); + expect(utils.clean(fn)).to.equal("var a = 1;"); }); it("should format es6 arrow functions with implicit return", function () { var fn = "() => foo()"; - utils.clean(fn).should.equal("foo()"); + expect(utils.clean(fn)).to.equal("foo()"); }); }); @@ -76,40 +77,48 @@ describe('lib/utils', function () { var stringify = utils.stringify; it('should return Buffer with .toJSON representation', function() { - stringify(new Buffer([0x01])).should.equal('[\n 1\n]'); - stringify(new Buffer([0x01, 0x02])).should.equal('[\n 1\n 2\n]'); + expect(stringify(new Buffer([0x01]))).to.equal('[\n 1\n]'); + expect(stringify(new Buffer([0x01, 0x02]))).to.equal('[\n 1\n 2\n]'); - stringify(new Buffer('ABCD')).should.equal('[\n 65\n 66\n 67\n 68\n]'); + expect(stringify(new Buffer('ABCD'))).to.equal('[\n 65\n 66\n 67\n 68\n]'); }); it('should return Date object with .toISOString() + string prefix', function() { - stringify(new Date(0)).should.equal('[Date: ' + new Date(0).toISOString() + ']'); + expect(stringify(new Date(0))).to.equal('[Date: ' + shimToISOString(new Date(0)) + ']'); var date = new Date(); // now - stringify(date).should.equal('[Date: ' + date.toISOString() + ']'); + expect(stringify(date)).to.equal('[Date: ' + shimToISOString(date) + ']'); + + function shimToISOString(date) { + if (date.toISOString) { + return date.toISOString(); + } else { + return toISOString(date); + } + } }); it('should return invalid Date object with .toString() + string prefix', function() { - stringify(new Date('')).should.equal('[Date: ' + new Date('').toString() + ']'); + expect(stringify(new Date(''))).to.equal('[Date: ' + new Date('').toString() + ']'); }); describe('#Number', function() { it('should show the handle -0 situations', function() { - stringify(-0).should.eql('-0'); - stringify(0).should.eql('0'); - stringify('-0').should.eql('"-0"'); + expect(stringify(-0)).to.eql('-0'); + expect(stringify(0)).to.eql('0'); + expect(stringify('-0')).to.eql('"-0"'); }); it('should work well with `NaN` and `Infinity`', function() { - stringify(NaN).should.equal('NaN'); - stringify(Infinity).should.equal('Infinity'); - stringify(-Infinity).should.equal('-Infinity'); + expect(stringify(NaN)).to.equal('NaN'); + expect(stringify(Infinity)).to.equal('Infinity'); + expect(stringify(-Infinity)).to.equal('-Infinity'); }); it('floats and ints', function() { - stringify(1).should.equal('1'); - stringify(1.2).should.equal('1.2'); - stringify(1e9).should.equal('1000000000'); + expect(stringify(1)).to.equal('1'); + expect(stringify(1.2)).to.equal('1.2'); + expect(stringify(1e9)).to.equal('1000000000'); }); }); @@ -184,7 +193,7 @@ describe('lib/utils', function () { , ' "undef": [undefined]' , ' "zero": -0' , '}'].join('\n'); - stringify(expected).should.equal(actual); + expect(stringify(expected)).to.equal(actual); }); }); @@ -192,28 +201,28 @@ describe('lib/utils', function () { var travis = { name: 'travis', age: 24 }; var travis2 = { age: 24, name: 'travis' }; - stringify(travis).should.equal(stringify(travis2)); + expect(stringify(travis)).to.equal(stringify(travis2)); }); it('should handle circular structures in objects', function(){ var travis = { name: 'travis' }; travis.whoami = travis; - stringify(travis).should.equal('{\n "name": "travis"\n "whoami": [Circular]\n}'); + expect(stringify(travis)).to.equal('{\n "name": "travis"\n "whoami": [Circular]\n}'); }); it('should handle circular structures in arrays', function(){ var travis = ['travis']; travis.push(travis); - stringify(travis).should.equal('[\n "travis"\n [Circular]\n]'); + expect(stringify(travis)).to.equal('[\n "travis"\n [Circular]\n]'); }); it('should handle circular structures in functions', function(){ var travis = function () {}; travis.fn = travis; - stringify(travis).should.equal('{\n "fn": [Circular]\n}'); + expect(stringify(travis)).to.equal('{\n "fn": [Circular]\n}'); }); @@ -222,46 +231,44 @@ describe('lib/utils', function () { regExpObj = { regexp: regexp }, regexpString = '/(?:)/'; - stringify(regExpObj).should.equal('{\n "regexp": ' + regexpString + '\n}'); - stringify(regexp).should.equal(regexpString); + expect(stringify(regExpObj)).to.equal('{\n "regexp": ' + regexpString + '\n}'); + expect(stringify(regexp)).to.equal(regexpString); var number = 1, numberObj = { number: number }, numberString = '1'; - stringify(numberObj).should.equal('{\n "number": ' + number + '\n}'); - stringify(number).should.equal(numberString); + expect(stringify(numberObj)).to.equal('{\n "number": ' + number + '\n}'); + expect(stringify(number)).to.equal(numberString); var boolean = false, booleanObj = { boolean: boolean }, booleanString = 'false'; - stringify(booleanObj).should.equal('{\n "boolean": ' + boolean + '\n}'); - stringify(boolean).should.equal(booleanString); + expect(stringify(booleanObj)).to.equal('{\n "boolean": ' + boolean + '\n}'); + expect(stringify(boolean)).to.equal(booleanString); var string = 'sneepy', stringObj = { string: string }; - stringify(stringObj).should.equal('{\n "string": "' + string + '"\n}'); - stringify(string).should.equal(JSON.stringify(string)); + expect(stringify(stringObj)).to.equal('{\n "string": "' + string + '"\n}'); + expect(stringify(string)).to.equal(JSON.stringify(string)); var nullValue = null, nullObj = { 'null': null }, nullString = '[null]'; - stringify(nullObj).should.equal('{\n "null": [null]\n}'); - stringify(nullValue).should.equal(nullString); + expect(stringify(nullObj)).to.equal('{\n "null": [null]\n}'); + expect(stringify(nullValue)).to.equal(nullString); }); it('should handle arrays', function () { var array = ['dave', 'dave', 'dave', 'dave'], arrayObj = {array: array}, - arrayString = array.map(function () { - return ' "dave"'; - }).join('\n'); + arrayString = ' "dave"\n "dave"\n "dave"\n "dave"' - stringify(arrayObj).should.equal('{\n "array": [\n' + arrayString + '\n ]\n}'); - stringify(array).should.equal('[' + arrayString.replace(/\s+/g, '\n ') + '\n]'); + expect(stringify(arrayObj)).to.equal('{\n "array": [\n' + arrayString + '\n ]\n}'); + expect(stringify(array)).to.equal('[' + arrayString.replace(/\s+/g, '\n ') + '\n]'); }); it('should handle functions', function () { @@ -269,159 +276,126 @@ describe('lib/utils', function () { fnObj = {fn: fn}, fnString = '[Function]'; - stringify(fnObj).should.equal('{\n "fn": ' + fnString + '\n}'); - stringify(fn).should.equal('[Function]'); + expect(stringify(fnObj)).to.equal('{\n "fn": ' + fnString + '\n}'); + expect(stringify(fn)).to.equal('[Function]'); }); it('should handle empty objects', function () { - stringify({}).should.equal('{}'); - stringify({foo: {}}).should.equal('{\n "foo": {}\n}'); + expect(stringify({})).to.equal('{}'); + expect(stringify({foo: {}})).to.equal('{\n "foo": {}\n}'); }); it('should handle empty arrays', function () { - stringify([]).should.equal('[]'); - stringify({foo: []}).should.equal('{\n "foo": []\n}'); + expect(stringify([])).to.equal('[]'); + expect(stringify({foo: []})).to.equal('{\n "foo": []\n}'); }); it('should handle non-empty arrays', function () { - stringify(['a', 'b', 'c']).should.equal('[\n "a"\n "b"\n "c"\n]') + expect(stringify(['a', 'b', 'c'])).to.equal('[\n "a"\n "b"\n "c"\n]') }); it('should handle empty functions (with no properties)', function () { - stringify(function(){}).should.equal('[Function]'); - stringify({foo: function() {}}).should.equal('{\n "foo": [Function]\n}'); - stringify({foo: function() {}, bar: 'baz'}).should.equal('{\n "bar": "baz"\n "foo": [Function]\n}'); + expect(stringify(function(){})).to.equal('[Function]'); + expect(stringify({foo: function() {}})).to.equal('{\n "foo": [Function]\n}'); + expect(stringify({foo: function() {}, bar: 'baz'})).to.equal('{\n "bar": "baz"\n "foo": [Function]\n}'); }); it('should handle functions w/ properties', function () { var fn = function(){}; fn.bar = 'baz'; - stringify(fn).should.equal('{\n "bar": "baz"\n}'); - stringify({foo: fn}).should.equal('{\n "foo": {\n "bar": "baz"\n }\n}'); + expect(stringify(fn)).to.equal('{\n "bar": "baz"\n}'); + expect(stringify({foo: fn})).to.equal('{\n "foo": {\n "bar": "baz"\n }\n}'); }); it('should handle undefined values', function () { - stringify({foo: undefined}).should.equal('{\n "foo": [undefined]\n}'); - stringify({foo: 'bar', baz: undefined}).should.equal('{\n "baz": [undefined]\n "foo": "bar"\n}'); - stringify().should.equal('[undefined]'); + expect(stringify({foo: undefined})).to.equal('{\n "foo": [undefined]\n}'); + expect(stringify({foo: 'bar', baz: undefined})).to.equal('{\n "baz": [undefined]\n "foo": "bar"\n}'); + expect(stringify()).to.equal('[undefined]'); }); it('should recurse', function () { - stringify({foo: {bar: {baz: {quux: {herp: 'derp'}}}}}).should.equal('{\n "foo": {\n "bar": {\n "baz": {\n "quux": {\n "herp": "derp"\n }\n }\n }\n }\n}'); + expect(stringify({foo: {bar: {baz: {quux: {herp: 'derp'}}}}})).to.equal('{\n "foo": {\n "bar": {\n "baz": {\n "quux": {\n "herp": "derp"\n }\n }\n }\n }\n}'); }); it('might get confusing', function () { - stringify(null).should.equal('[null]'); + expect(stringify(null)).to.equal('[null]'); }); it('should not freak out if it sees a primitive twice', function () { - stringify({foo: null, bar: null}).should.equal('{\n "bar": [null]\n "foo": [null]\n}'); - stringify({foo: 1, bar: 1}).should.equal('{\n "bar": 1\n "foo": 1\n}'); + expect(stringify({foo: null, bar: null})).to.equal('{\n "bar": [null]\n "foo": [null]\n}'); + expect(stringify({foo: 1, bar: 1})).to.equal('{\n "bar": 1\n "foo": 1\n}'); }); it('should stringify dates', function () { var date = new Date(0); - stringify(date).should.equal('[Date: 1970-01-01T00:00:00.000Z]'); - stringify({date: date}).should.equal('{\n "date": [Date: 1970-01-01T00:00:00.000Z]\n}'); + expect(stringify(date)).to.equal('[Date: 1970-01-01T00:00:00.000Z]'); + expect(stringify({date: date})).to.equal('{\n "date": [Date: 1970-01-01T00:00:00.000Z]\n}'); }); it('should handle object without an Object prototype', function () { - var a = Object.create(null); + var a; + if (Object.create) { + a = Object.create(null); + } else { + a = {}; + } a.foo = 1; - stringify(a).should.equal('{\n "foo": 1\n}'); + expect(stringify(a)).to.equal('{\n "foo": 1\n}'); }); // In old version node.js, Symbol is not available by default. if (typeof global.Symbol === 'function') { it('should handle Symbol', function () { var symbol = Symbol('value'); - stringify(symbol).should.equal('Symbol(value)'); - stringify({symbol: symbol}).should.equal('{\n "symbol": Symbol(value)\n}') + expect(stringify(symbol)).to.equal('Symbol(value)'); + expect(stringify({symbol: symbol})).to.equal('{\n "symbol": Symbol(value)\n}') }); } it('should handle length properties that cannot be coerced to a number', function () { - stringify({length: {toString: 0}}).should.equal('{\n "length": {\n "toString": 0\n }\n}'); + expect(stringify({length: {nonBuiltinProperty: 0}})).to.equal('{\n "length": {\n "nonBuiltinProperty": 0\n }\n}'); + expect(stringify({length: "a string where length should be"})).to.equal('{\n "length": "a string where length should be"\n}'); }); }); describe('type', function () { var type = utils.type; - it('should recognize various types', function () { - type({}).should.equal('object'); - type([]).should.equal('array'); - type(1).should.equal('number'); - type(Infinity).should.equal('number'); - type(null).should.equal('null'); - type(undefined).should.equal('undefined'); - type(new Date()).should.equal('date'); - type(/foo/).should.equal('regexp'); - type('type').should.equal('string'); - type(global).should.equal('global'); - type(true).should.equal('boolean'); - }); - - describe('when toString on null or undefined stringifies window', function () { - var toString = Object.prototype.toString; + var toString = Object.prototype.toString; - beforeEach(function () { - // some JS engines such as PhantomJS 1.x exhibit this behavior - Object.prototype.toString = function () { + beforeEach(function() { + // some JS engines such as PhantomJS 1.x exhibit this behavior + Object.prototype.toString = function() { + if (this === global) { return '[object DOMWindow]'; - }; - }); - - it('should recognize null and undefined', function () { - type(null).should.equal('null'); - type(undefined).should.equal('undefined'); - }); - - afterEach(function () { - Object.prototype.toString = toString; - }); - }); - }); - - describe('lookupFiles', function () { - var fs = require('fs'), - path = require('path'), - existsSync = fs.existsSync || path.existsSync; - - beforeEach(function () { - fs.writeFileSync('/tmp/mocha-utils.js', 'yippy skippy ying yang yow'); - fs.symlinkSync('/tmp/mocha-utils.js', '/tmp/mocha-utils-link.js'); + } + return toString.call(this); + }; }); - it('should not choke on symlinks', function () { - utils.lookupFiles('/tmp', ['js'], false) - .should.containEql('/tmp/mocha-utils-link.js') - .and.containEql('/tmp/mocha-utils.js') - .and.have.lengthOf(2); - existsSync('/tmp/mocha-utils-link.js').should.be.true(); - fs.renameSync('/tmp/mocha-utils.js', '/tmp/bob'); - existsSync('/tmp/mocha-utils-link.js').should.be.false(); - utils.lookupFiles('/tmp', ['js'], false).should.eql([]); + it('should recognize various types', function () { + expect(type({})).to.equal('object'); + expect(type([])).to.equal('array'); + expect(type(1)).to.equal('number'); + expect(type(Infinity)).to.equal('number'); + expect(type(null)).to.equal('null'); + expect(type(undefined)).to.equal('undefined'); + expect(type(new Date())).to.equal('date'); + expect(type(/foo/)).to.equal('regexp'); + expect(type('type')).to.equal('string'); + expect(type(global)).to.equal('domwindow'); + expect(type(true)).to.equal('boolean'); }); - it('should accept a glob "path" value', function () { - utils.lookupFiles('/tmp/mocha-utils*', ['js'], false) - .should - .containEql('/tmp/mocha-utils-link.js') - .and - .containEql('/tmp/mocha-utils.js') - .and - .have - .lengthOf(2); + describe('when toString on null or undefined stringifies window', function () { + it('should recognize null and undefined', function () { + expect(type(null)).to.equal('null'); + expect(type(undefined)).to.equal('undefined'); + }); }); afterEach(function () { - ['/tmp/mocha-utils.js', '/tmp/mocha-utils-link.js', '/tmp/bob'].forEach(function (path) { - try { - fs.unlinkSync(path); - } - catch (ignored) {} - }); + Object.prototype.toString = toString; }); }); }); diff --git a/test/browser-fixtures/bdd.js b/test/browser-fixtures/bdd.js new file mode 100644 index 0000000000..72b4a8a47c --- /dev/null +++ b/test/browser-fixtures/bdd.js @@ -0,0 +1,4 @@ +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('bdd'); diff --git a/test/browser-fixtures/exports.js b/test/browser-fixtures/exports.js new file mode 100644 index 0000000000..32c26a12ff --- /dev/null +++ b/test/browser-fixtures/exports.js @@ -0,0 +1,4 @@ +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('exports'); diff --git a/test/browser-fixtures/qunit.js b/test/browser-fixtures/qunit.js new file mode 100644 index 0000000000..8804d0b994 --- /dev/null +++ b/test/browser-fixtures/qunit.js @@ -0,0 +1,4 @@ +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('qunit'); diff --git a/test/browser-fixtures/tdd.js b/test/browser-fixtures/tdd.js new file mode 100644 index 0000000000..997a47dc18 --- /dev/null +++ b/test/browser-fixtures/tdd.js @@ -0,0 +1,4 @@ +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('tdd'); diff --git a/test/fixture-expect.js b/test/fixture-expect.js new file mode 100644 index 0000000000..cacc78425a --- /dev/null +++ b/test/fixture-expect.js @@ -0,0 +1 @@ +global.expect = require("expect.js") diff --git a/test/mocha.opts b/test/mocha.opts index 3c2f2cbd02..cd797e2ae0 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,4 +1,5 @@ --require should +--require ./test/fixture-expect.js --reporter dot --ui bdd --globals okGlobalA,okGlobalB