From f016bdbc35b7efa44bd63413bde09433ea916c59 Mon Sep 17 00:00:00 2001 From: HumairAK Date: Tue, 26 Jul 2016 03:43:04 -0400 Subject: added some unit testing, need a lot more --- node_modules/.bin/_mocha | 1 + node_modules/.bin/mocha | 1 + node_modules/chai-http/History.md | 94 + node_modules/chai-http/dist/chai-http.js | 5309 ++++++++ node_modules/chai-http/index.js | 3 + node_modules/chai-http/lib/http.js | 364 + node_modules/chai-http/lib/net.js | 14 + node_modules/chai-http/lib/request.js | 311 + .../chai-http/node_modules/cookiejar/.npmignore | 1 + .../chai-http/node_modules/cookiejar/LICENSE | 9 + .../chai-http/node_modules/cookiejar/cookiejar.js | 261 + .../chai-http/node_modules/cookiejar/package.json | 54 + .../chai-http/node_modules/cookiejar/readme.md | 57 + .../chai-http/node_modules/cookiejar/tests/test.js | 82 + node_modules/chai-http/node_modules/is-ip/index.js | 14 + .../is-ip/node_modules/ip-regex/index.js | 20 + .../is-ip/node_modules/ip-regex/license | 21 + .../is-ip/node_modules/ip-regex/package.json | 68 + .../is-ip/node_modules/ip-regex/readme.md | 59 + .../chai-http/node_modules/is-ip/package.json | 72 + .../chai-http/node_modules/is-ip/readme.md | 46 + .../chai-http/node_modules/superagent/.npmignore | 7 + .../chai-http/node_modules/superagent/.travis.yml | 17 + .../chai-http/node_modules/superagent/.zuul.yml | 15 + .../node_modules/superagent/Contributing.md | 7 + .../chai-http/node_modules/superagent/History.md | 584 + .../chai-http/node_modules/superagent/LICENSE | 22 + .../chai-http/node_modules/superagent/Makefile | 57 + .../chai-http/node_modules/superagent/Readme.md | 130 + .../node_modules/superagent/component.json | 20 + .../node_modules/superagent/docs/head.html | 10 + .../node_modules/superagent/docs/images/bg.png | Bin 0 -> 8856 bytes .../node_modules/superagent/docs/index.md | 476 + .../node_modules/superagent/docs/style.css | 81 + .../node_modules/superagent/docs/tail.html | 29 + .../node_modules/superagent/docs/test.html | 2082 +++ .../node_modules/superagent/lib/client.js | 974 ++ .../node_modules/superagent/lib/is-object.js | 13 + .../node_modules/superagent/lib/node/agent.js | 82 + .../node_modules/superagent/lib/node/index.js | 952 ++ .../superagent/lib/node/parsers/image.js | 10 + .../superagent/lib/node/parsers/index.js | 5 + .../superagent/lib/node/parsers/json.js | 19 + .../superagent/lib/node/parsers/text.js | 7 + .../superagent/lib/node/parsers/urlencoded.js | 19 + .../node_modules/superagent/lib/node/part.js | 149 + .../node_modules/superagent/lib/node/response.js | 215 + .../node_modules/superagent/lib/node/utils.js | 142 + .../node_modules/superagent/lib/request-base.js | 347 + .../node_modules/superagent/lib/request.js | 32 + .../node_modules/component-emitter/History.md | 68 + .../node_modules/component-emitter/LICENSE | 24 + .../node_modules/component-emitter/Readme.md | 74 + .../node_modules/component-emitter/index.js | 163 + .../node_modules/component-emitter/package.json | 182 + .../superagent/node_modules/extend/.eslintrc | 192 + .../superagent/node_modules/extend/.jscs.json | 104 + .../superagent/node_modules/extend/.npmignore | 1 + .../superagent/node_modules/extend/.travis.yml | 44 + .../superagent/node_modules/extend/CHANGELOG.md | 69 + .../superagent/node_modules/extend/LICENSE | 23 + .../superagent/node_modules/extend/README.md | 62 + .../superagent/node_modules/extend/component.json | 32 + .../superagent/node_modules/extend/index.js | 86 + .../superagent/node_modules/extend/package.json | 73 + .../node_modules/form-data/.dockerignore | 7 + .../node_modules/form-data/.editorconfig | 10 + .../node_modules/form-data/.eslintignore | 1 + .../superagent/node_modules/form-data/.eslintrc | 64 + .../superagent/node_modules/form-data/License | 19 + .../superagent/node_modules/form-data/README.md | 218 + .../node_modules/form-data/lib/browser.js | 2 + .../node_modules/form-data/lib/form_data.js | 411 + .../node_modules/form-data/lib/populate.js | 9 + .../form-data/node_modules/async/CHANGELOG.md | 125 + .../form-data/node_modules/async/LICENSE | 19 + .../form-data/node_modules/async/README.md | 1877 +++ .../form-data/node_modules/async/dist/async.js | 1265 ++ .../form-data/node_modules/async/dist/async.min.js | 2 + .../form-data/node_modules/async/lib/async.js | 1265 ++ .../form-data/node_modules/async/package.json | 123 + .../form-data/node_modules/combined-stream/License | 19 + .../node_modules/combined-stream/Readme.md | 138 + .../combined-stream/lib/combined_stream.js | 188 + .../node_modules/delayed-stream/.npmignore | 1 + .../node_modules/delayed-stream/License | 19 + .../node_modules/delayed-stream/Makefile | 7 + .../node_modules/delayed-stream/Readme.md | 141 + .../delayed-stream/lib/delayed_stream.js | 107 + .../node_modules/delayed-stream/package.json | 64 + .../node_modules/combined-stream/package.json | 67 + .../superagent/node_modules/form-data/package.json | 104 + .../superagent/node_modules/form-data/wercker.yml | 36 + .../superagent/node_modules/formidable/.npmignore | 7 + .../superagent/node_modules/formidable/.travis.yml | 5 + .../superagent/node_modules/formidable/LICENSE | 7 + .../superagent/node_modules/formidable/Readme.md | 425 + .../superagent/node_modules/formidable/index.js | 1 + .../superagent/node_modules/formidable/lib/file.js | 72 + .../node_modules/formidable/lib/incoming_form.js | 555 + .../node_modules/formidable/lib/index.js | 3 + .../node_modules/formidable/lib/json_parser.js | 35 + .../formidable/lib/multipart_parser.js | 332 + .../node_modules/formidable/lib/octet_parser.js | 20 + .../formidable/lib/querystring_parser.js | 27 + .../node_modules/formidable/package.json | 66 + .../node_modules/readable-stream/.npmignore | 8 + .../node_modules/readable-stream/.travis.yml | 54 + .../node_modules/readable-stream/LICENSE | 18 + .../node_modules/readable-stream/README.md | 36 + .../node_modules/readable-stream/doc/stream.md | 1772 +++ .../readable-stream/doc/wg-meetings/2015-01-30.md | 60 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 75 + .../readable-stream/lib/_stream_passthrough.js | 26 + .../readable-stream/lib/_stream_readable.js | 893 ++ .../readable-stream/lib/_stream_transform.js | 180 + .../readable-stream/lib/_stream_writable.js | 526 + .../node_modules/buffer-shims/index.js | 108 + .../node_modules/buffer-shims/license.md | 19 + .../node_modules/buffer-shims/package.json | 49 + .../node_modules/buffer-shims/readme.md | 21 + .../node_modules/isarray/.npmignore | 1 + .../node_modules/isarray/.travis.yml | 4 + .../readable-stream/node_modules/isarray/Makefile | 6 + .../readable-stream/node_modules/isarray/README.md | 60 + .../node_modules/isarray/component.json | 19 + .../readable-stream/node_modules/isarray/index.js | 5 + .../node_modules/isarray/package.json | 71 + .../readable-stream/node_modules/isarray/test.js | 20 + .../node_modules/process-nextick-args/.travis.yml | 12 + .../node_modules/process-nextick-args/index.js | 43 + .../node_modules/process-nextick-args/license.md | 19 + .../node_modules/process-nextick-args/package.json | 49 + .../node_modules/process-nextick-args/readme.md | 18 + .../node_modules/process-nextick-args/test.js | 24 + .../node_modules/util-deprecate/History.md | 16 + .../node_modules/util-deprecate/LICENSE | 24 + .../node_modules/util-deprecate/README.md | 53 + .../node_modules/util-deprecate/browser.js | 67 + .../node_modules/util-deprecate/node.js | 6 + .../node_modules/util-deprecate/package.json | 54 + .../node_modules/readable-stream/package.json | 90 + .../node_modules/readable-stream/passthrough.js | 1 + .../node_modules/readable-stream/readable.js | 16 + .../node_modules/readable-stream/transform.js | 1 + .../node_modules/readable-stream/writable.js | 1 + .../chai-http/node_modules/superagent/package.json | 145 + .../node_modules/superagent/superagent.js | 1541 +++ node_modules/chai-http/package.json | 112 + node_modules/chai/.npmignore | 14 + node_modules/chai/CODE_OF_CONDUCT.md | 58 + node_modules/chai/CONTRIBUTING.md | 214 + node_modules/chai/History.md | 1059 ++ node_modules/chai/README.md | 83 + node_modules/chai/ReleaseNotes.md | 737 ++ node_modules/chai/bower.json | 26 + node_modules/chai/chai.js | 6142 +++++++++ node_modules/chai/index.js | 1 + node_modules/chai/karma.conf.js | 28 + node_modules/chai/karma.sauce.js | 41 + node_modules/chai/lib/chai.js | 93 + node_modules/chai/lib/chai/assertion.js | 131 + node_modules/chai/lib/chai/config.js | 55 + node_modules/chai/lib/chai/core/assertions.js | 1860 +++ node_modules/chai/lib/chai/interface/assert.js | 1645 +++ node_modules/chai/lib/chai/interface/expect.js | 34 + node_modules/chai/lib/chai/interface/should.js | 201 + .../chai/lib/chai/utils/addChainableMethod.js | 112 + node_modules/chai/lib/chai/utils/addMethod.js | 44 + node_modules/chai/lib/chai/utils/addProperty.js | 48 + node_modules/chai/lib/chai/utils/expectTypes.js | 42 + node_modules/chai/lib/chai/utils/flag.js | 33 + node_modules/chai/lib/chai/utils/getActual.js | 20 + .../chai/lib/chai/utils/getEnumerableProperties.js | 26 + node_modules/chai/lib/chai/utils/getMessage.js | 51 + node_modules/chai/lib/chai/utils/getName.js | 22 + node_modules/chai/lib/chai/utils/getPathInfo.js | 111 + node_modules/chai/lib/chai/utils/getPathValue.js | 43 + node_modules/chai/lib/chai/utils/getProperties.js | 36 + node_modules/chai/lib/chai/utils/hasProperty.js | 64 + node_modules/chai/lib/chai/utils/index.js | 130 + node_modules/chai/lib/chai/utils/inspect.js | 335 + node_modules/chai/lib/chai/utils/objDisplay.js | 50 + .../lib/chai/utils/overwriteChainableMethod.js | 54 + .../chai/lib/chai/utils/overwriteMethod.js | 52 + .../chai/lib/chai/utils/overwriteProperty.js | 55 + node_modules/chai/lib/chai/utils/test.js | 28 + node_modules/chai/lib/chai/utils/transferFlags.js | 45 + .../chai/node_modules/assertion-error/.npmignore | 11 + .../chai/node_modules/assertion-error/History.md | 19 + .../chai/node_modules/assertion-error/README.md | 41 + .../chai/node_modules/assertion-error/index.js | 116 + .../chai/node_modules/assertion-error/package.json | 61 + node_modules/chai/node_modules/deep-eql/.npmignore | 11 + node_modules/chai/node_modules/deep-eql/History.md | 28 + node_modules/chai/node_modules/deep-eql/README.md | 52 + node_modules/chai/node_modules/deep-eql/index.js | 1 + .../chai/node_modules/deep-eql/karma.conf.js | 20 + node_modules/chai/node_modules/deep-eql/lib/eql.js | 257 + .../deep-eql/node_modules/type-detect/.npmignore | 11 + .../deep-eql/node_modules/type-detect/History.md | 18 + .../deep-eql/node_modules/type-detect/README.md | 193 + .../deep-eql/node_modules/type-detect/index.js | 1 + .../deep-eql/node_modules/type-detect/lib/type.js | 142 + .../deep-eql/node_modules/type-detect/package.json | 56 + .../chai/node_modules/deep-eql/package.json | 63 + .../chai/node_modules/type-detect/.npmignore | 11 + .../chai/node_modules/type-detect/History.md | 52 + .../chai/node_modules/type-detect/README.md | 226 + .../chai/node_modules/type-detect/ReleaseNotes.md | 46 + .../chai/node_modules/type-detect/index.js | 1 + .../chai/node_modules/type-detect/lib/type.js | 134 + .../chai/node_modules/type-detect/package.json | 59 + node_modules/chai/package.json | 93 + node_modules/chai/sauce.browsers.js | 128 + node_modules/mocha/CHANGELOG.md | 1262 ++ node_modules/mocha/LICENSE | 22 + node_modules/mocha/bin/.eslintrc | 3 + node_modules/mocha/bin/_mocha | 480 + node_modules/mocha/bin/mocha | 73 + node_modules/mocha/bin/options.js | 39 + node_modules/mocha/images/error.png | Bin 0 -> 412 bytes node_modules/mocha/images/ok.png | Bin 0 -> 388 bytes node_modules/mocha/index.js | 3 + node_modules/mocha/lib/browser/debug.js | 4 + node_modules/mocha/lib/browser/events.js | 193 + node_modules/mocha/lib/browser/progress.js | 117 + node_modules/mocha/lib/browser/tty.js | 11 + node_modules/mocha/lib/context.js | 104 + node_modules/mocha/lib/hook.js | 46 + node_modules/mocha/lib/interfaces/bdd.js | 117 + node_modules/mocha/lib/interfaces/common.js | 85 + node_modules/mocha/lib/interfaces/exports.js | 61 + node_modules/mocha/lib/interfaces/index.js | 4 + node_modules/mocha/lib/interfaces/qunit.js | 94 + node_modules/mocha/lib/interfaces/tdd.js | 106 + node_modules/mocha/lib/mocha.js | 503 + node_modules/mocha/lib/ms.js | 128 + node_modules/mocha/lib/pending.js | 15 + node_modules/mocha/lib/reporters/base.js | 487 + node_modules/mocha/lib/reporters/doc.js | 62 + node_modules/mocha/lib/reporters/dot.js | 66 + node_modules/mocha/lib/reporters/html-cov.js | 56 + node_modules/mocha/lib/reporters/html.js | 343 + node_modules/mocha/lib/reporters/index.js | 19 + node_modules/mocha/lib/reporters/json-cov.js | 151 + node_modules/mocha/lib/reporters/json-stream.js | 60 + node_modules/mocha/lib/reporters/json.js | 90 + node_modules/mocha/lib/reporters/landing.js | 92 + node_modules/mocha/lib/reporters/list.js | 61 + node_modules/mocha/lib/reporters/markdown.js | 97 + node_modules/mocha/lib/reporters/min.js | 36 + node_modules/mocha/lib/reporters/nyan.js | 261 + node_modules/mocha/lib/reporters/progress.js | 89 + node_modules/mocha/lib/reporters/spec.js | 83 + node_modules/mocha/lib/reporters/tap.js | 68 + .../mocha/lib/reporters/templates/coverage.jade | 51 + .../mocha/lib/reporters/templates/menu.jade | 13 + .../mocha/lib/reporters/templates/script.html | 34 + .../mocha/lib/reporters/templates/style.html | 324 + node_modules/mocha/lib/reporters/xunit.js | 166 + node_modules/mocha/lib/runnable.js | 363 + node_modules/mocha/lib/runner.js | 894 ++ node_modules/mocha/lib/suite.js | 395 + node_modules/mocha/lib/template.html | 18 + node_modules/mocha/lib/test.js | 44 + node_modules/mocha/lib/utils.js | 750 ++ node_modules/mocha/mocha.css | 314 + node_modules/mocha/mocha.js | 13149 +++++++++++++++++++ node_modules/mocha/node_modules/.bin/jade | 1 + node_modules/mocha/node_modules/.bin/mkdirp | 1 + .../mocha/node_modules/.bin/supports-color | 1 + .../mocha/node_modules/commander/Readme.md | 208 + node_modules/mocha/node_modules/commander/index.js | 876 ++ .../mocha/node_modules/commander/package.json | 71 + node_modules/mocha/node_modules/diff/README.md | 181 + node_modules/mocha/node_modules/diff/diff.js | 619 + node_modules/mocha/node_modules/diff/package.json | 64 + .../node_modules/escape-string-regexp/index.js | 11 + .../node_modules/escape-string-regexp/package.json | 69 + .../node_modules/escape-string-regexp/readme.md | 27 + node_modules/mocha/node_modules/glob/.npmignore | 2 + node_modules/mocha/node_modules/glob/.travis.yml | 3 + node_modules/mocha/node_modules/glob/LICENSE | 27 + node_modules/mocha/node_modules/glob/README.md | 250 + node_modules/mocha/node_modules/glob/examples/g.js | 9 + .../mocha/node_modules/glob/examples/usr-local.js | 9 + node_modules/mocha/node_modules/glob/glob.js | 728 + .../glob/node_modules/minimatch/.npmignore | 1 + .../glob/node_modules/minimatch/LICENSE | 23 + .../glob/node_modules/minimatch/README.md | 218 + .../glob/node_modules/minimatch/minimatch.js | 1061 ++ .../minimatch/node_modules/lru-cache/.npmignore | 1 + .../minimatch/node_modules/lru-cache/.travis.yml | 8 + .../minimatch/node_modules/lru-cache/CONTRIBUTORS | 14 + .../minimatch/node_modules/lru-cache/LICENSE | 15 + .../minimatch/node_modules/lru-cache/README.md | 137 + .../node_modules/lru-cache/lib/lru-cache.js | 334 + .../minimatch/node_modules/lru-cache/package.json | 58 + .../minimatch/node_modules/lru-cache/test/basic.js | 396 + .../node_modules/lru-cache/test/foreach.js | 120 + .../node_modules/lru-cache/test/memory-leak.js | 51 + .../node_modules/lru-cache/test/serialize.js | 216 + .../minimatch/node_modules/sigmund/LICENSE | 15 + .../minimatch/node_modules/sigmund/README.md | 53 + .../minimatch/node_modules/sigmund/bench.js | 283 + .../minimatch/node_modules/sigmund/package.json | 60 + .../minimatch/node_modules/sigmund/sigmund.js | 39 + .../minimatch/node_modules/sigmund/test/basic.js | 24 + .../glob/node_modules/minimatch/package.json | 58 + .../glob/node_modules/minimatch/test/basic.js | 399 + .../node_modules/minimatch/test/brace-expand.js | 33 + .../glob/node_modules/minimatch/test/caching.js | 14 + .../glob/node_modules/minimatch/test/defaults.js | 274 + .../test/extglob-ending-with-state-char.js | 8 + node_modules/mocha/node_modules/glob/package.json | 58 + .../mocha/node_modules/glob/test/00-setup.js | 176 + .../node_modules/glob/test/bash-comparison.js | 63 + .../mocha/node_modules/glob/test/bash-results.json | 351 + .../mocha/node_modules/glob/test/cwd-test.js | 55 + .../mocha/node_modules/glob/test/globstar-match.js | 19 + node_modules/mocha/node_modules/glob/test/mark.js | 118 + .../glob/test/new-glob-optional-options.js | 10 + .../mocha/node_modules/glob/test/nocase-nomagic.js | 113 + .../mocha/node_modules/glob/test/pause-resume.js | 73 + .../mocha/node_modules/glob/test/readme-issue.js | 36 + .../mocha/node_modules/glob/test/root-nomount.js | 39 + node_modules/mocha/node_modules/glob/test/root.js | 46 + node_modules/mocha/node_modules/glob/test/stat.js | 32 + .../mocha/node_modules/glob/test/zz-cleanup.js | 11 + node_modules/mocha/node_modules/growl/History.md | 63 + node_modules/mocha/node_modules/growl/Readme.md | 108 + node_modules/mocha/node_modules/growl/lib/growl.js | 290 + node_modules/mocha/node_modules/growl/package.json | 51 + node_modules/mocha/node_modules/growl/test.js | 31 + node_modules/mocha/node_modules/jade/.npmignore | 15 + node_modules/mocha/node_modules/jade/LICENSE | 22 + node_modules/mocha/node_modules/jade/bin/jade | 147 + node_modules/mocha/node_modules/jade/index.js | 4 + node_modules/mocha/node_modules/jade/jade.js | 3586 +++++ node_modules/mocha/node_modules/jade/jade.md | 510 + node_modules/mocha/node_modules/jade/jade.min.js | 2 + .../mocha/node_modules/jade/lib/compiler.js | 642 + .../mocha/node_modules/jade/lib/doctypes.js | 18 + .../mocha/node_modules/jade/lib/filters.js | 97 + .../mocha/node_modules/jade/lib/inline-tags.js | 28 + node_modules/mocha/node_modules/jade/lib/jade.js | 237 + node_modules/mocha/node_modules/jade/lib/lexer.js | 771 ++ .../mocha/node_modules/jade/lib/nodes/attrs.js | 77 + .../node_modules/jade/lib/nodes/block-comment.js | 33 + .../mocha/node_modules/jade/lib/nodes/block.js | 121 + .../mocha/node_modules/jade/lib/nodes/case.js | 43 + .../mocha/node_modules/jade/lib/nodes/code.js | 35 + .../mocha/node_modules/jade/lib/nodes/comment.js | 32 + .../mocha/node_modules/jade/lib/nodes/doctype.js | 29 + .../mocha/node_modules/jade/lib/nodes/each.js | 35 + .../mocha/node_modules/jade/lib/nodes/filter.js | 35 + .../mocha/node_modules/jade/lib/nodes/index.js | 20 + .../mocha/node_modules/jade/lib/nodes/literal.js | 32 + .../mocha/node_modules/jade/lib/nodes/mixin.js | 36 + .../mocha/node_modules/jade/lib/nodes/node.js | 25 + .../mocha/node_modules/jade/lib/nodes/tag.js | 95 + .../mocha/node_modules/jade/lib/nodes/text.js | 36 + node_modules/mocha/node_modules/jade/lib/parser.js | 710 + .../mocha/node_modules/jade/lib/runtime.js | 174 + .../mocha/node_modules/jade/lib/self-closing.js | 19 + node_modules/mocha/node_modules/jade/lib/utils.js | 49 + .../jade/node_modules/commander/.npmignore | 4 + .../jade/node_modules/commander/.travis.yml | 4 + .../jade/node_modules/commander/History.md | 107 + .../jade/node_modules/commander/Makefile | 7 + .../jade/node_modules/commander/Readme.md | 262 + .../jade/node_modules/commander/index.js | 2 + .../jade/node_modules/commander/lib/commander.js | 1026 ++ .../jade/node_modules/commander/package.json | 60 + .../jade/node_modules/mkdirp/.gitignore.orig | 2 + .../jade/node_modules/mkdirp/.gitignore.rej | 5 + .../jade/node_modules/mkdirp/.npmignore | 2 + .../node_modules/jade/node_modules/mkdirp/LICENSE | 21 + .../jade/node_modules/mkdirp/README.markdown | 54 + .../jade/node_modules/mkdirp/examples/pow.js | 6 + .../jade/node_modules/mkdirp/examples/pow.js.orig | 6 + .../jade/node_modules/mkdirp/examples/pow.js.rej | 19 + .../node_modules/jade/node_modules/mkdirp/index.js | 79 + .../jade/node_modules/mkdirp/package.json | 58 + .../jade/node_modules/mkdirp/test/chmod.js | 38 + .../jade/node_modules/mkdirp/test/clobber.js | 37 + .../jade/node_modules/mkdirp/test/mkdirp.js | 28 + .../jade/node_modules/mkdirp/test/perm.js | 32 + .../jade/node_modules/mkdirp/test/perm_sync.js | 39 + .../jade/node_modules/mkdirp/test/race.js | 41 + .../jade/node_modules/mkdirp/test/rel.js | 32 + .../jade/node_modules/mkdirp/test/sync.js | 27 + .../jade/node_modules/mkdirp/test/umask.js | 28 + .../jade/node_modules/mkdirp/test/umask_sync.js | 27 + node_modules/mocha/node_modules/jade/package.json | 62 + node_modules/mocha/node_modules/jade/runtime.js | 179 + .../mocha/node_modules/jade/runtime.min.js | 1 + node_modules/mocha/node_modules/jade/test.jade | 7 + .../mocha/node_modules/jade/testing/head.jade | 5 + .../mocha/node_modules/jade/testing/index.jade | 22 + .../mocha/node_modules/jade/testing/index.js | 11 + .../mocha/node_modules/jade/testing/layout.jade | 6 + .../mocha/node_modules/jade/testing/user.jade | 7 + .../mocha/node_modules/jade/testing/user.js | 27 + node_modules/mocha/node_modules/mkdirp/.travis.yml | 8 + node_modules/mocha/node_modules/mkdirp/LICENSE | 21 + node_modules/mocha/node_modules/mkdirp/bin/cmd.js | 33 + .../mocha/node_modules/mkdirp/bin/usage.txt | 12 + .../mocha/node_modules/mkdirp/examples/pow.js | 6 + node_modules/mocha/node_modules/mkdirp/index.js | 98 + .../mkdirp/node_modules/minimist/.travis.yml | 4 + .../mkdirp/node_modules/minimist/LICENSE | 18 + .../mkdirp/node_modules/minimist/example/parse.js | 2 + .../mkdirp/node_modules/minimist/index.js | 187 + .../mkdirp/node_modules/minimist/package.json | 67 + .../mkdirp/node_modules/minimist/readme.markdown | 73 + .../mkdirp/node_modules/minimist/test/dash.js | 24 + .../node_modules/minimist/test/default_bool.js | 20 + .../mkdirp/node_modules/minimist/test/dotted.js | 16 + .../mkdirp/node_modules/minimist/test/long.js | 31 + .../mkdirp/node_modules/minimist/test/parse.js | 318 + .../node_modules/minimist/test/parse_modified.js | 9 + .../mkdirp/node_modules/minimist/test/short.js | 67 + .../node_modules/minimist/test/whitespace.js | 8 + .../mocha/node_modules/mkdirp/package.json | 60 + .../mocha/node_modules/mkdirp/readme.markdown | 100 + .../mocha/node_modules/mkdirp/test/chmod.js | 41 + .../mocha/node_modules/mkdirp/test/clobber.js | 38 + .../mocha/node_modules/mkdirp/test/mkdirp.js | 28 + .../mocha/node_modules/mkdirp/test/opts_fs.js | 29 + .../mocha/node_modules/mkdirp/test/opts_fs_sync.js | 27 + .../mocha/node_modules/mkdirp/test/perm.js | 32 + .../mocha/node_modules/mkdirp/test/perm_sync.js | 36 + .../mocha/node_modules/mkdirp/test/race.js | 37 + node_modules/mocha/node_modules/mkdirp/test/rel.js | 32 + .../mocha/node_modules/mkdirp/test/return.js | 25 + .../mocha/node_modules/mkdirp/test/return_sync.js | 24 + .../mocha/node_modules/mkdirp/test/root.js | 19 + .../mocha/node_modules/mkdirp/test/sync.js | 32 + .../mocha/node_modules/mkdirp/test/umask.js | 28 + .../mocha/node_modules/mkdirp/test/umask_sync.js | 32 + .../mocha/node_modules/supports-color/cli.js | 29 + .../mocha/node_modules/supports-color/index.js | 39 + .../mocha/node_modules/supports-color/package.json | 85 + .../mocha/node_modules/supports-color/readme.md | 44 + .../mocha/node_modules/to-iso-string/.npmignore | 3 + .../mocha/node_modules/to-iso-string/History.md | 9 + .../mocha/node_modules/to-iso-string/Makefile | 17 + .../mocha/node_modules/to-iso-string/Readme.md | 18 + .../node_modules/to-iso-string/component.json | 9 + .../mocha/node_modules/to-iso-string/index.js | 40 + .../mocha/node_modules/to-iso-string/package.json | 50 + .../mocha/node_modules/to-iso-string/test/index.js | 10 + node_modules/mocha/package.json | 1281 ++ node_modules/supertest/.npmignore | 1 + node_modules/supertest/.travis.yml | 6 + node_modules/supertest/History.md | 181 + node_modules/supertest/LICENSE | 22 + node_modules/supertest/Readme.md | 222 + node_modules/supertest/example.js | 20 + node_modules/supertest/index.js | 45 + node_modules/supertest/lib/agent.js | 54 + node_modules/supertest/lib/test.js | 270 + .../supertest/node_modules/superagent/.npmignore | 6 + .../supertest/node_modules/superagent/.travis.yml | 18 + .../supertest/node_modules/superagent/.zuul.yml | 15 + .../node_modules/superagent/Contributing.md | 7 + .../supertest/node_modules/superagent/History.md | 554 + .../supertest/node_modules/superagent/LICENSE | 22 + .../supertest/node_modules/superagent/Makefile | 57 + .../supertest/node_modules/superagent/Readme.md | 116 + .../supertest/node_modules/superagent/bower.json | 4 + .../node_modules/superagent/component.json | 21 + .../node_modules/superagent/docs/head.html | 21 + .../node_modules/superagent/docs/highlight.js | 17 + .../node_modules/superagent/docs/images/bg.png | Bin 0 -> 8856 bytes .../node_modules/superagent/docs/index.md | 448 + .../node_modules/superagent/docs/jquery-ui.min.js | 6 + .../node_modules/superagent/docs/jquery.js | 4 + .../superagent/docs/jquery.tocify.min.js | 4 + .../node_modules/superagent/docs/style.css | 81 + .../node_modules/superagent/docs/tail.html | 4 + .../node_modules/superagent/docs/test.html | 2082 +++ .../node_modules/superagent/lib/client.js | 1077 ++ .../node_modules/superagent/lib/is-object.js | 13 + .../node_modules/superagent/lib/node/agent.js | 82 + .../node_modules/superagent/lib/node/index.js | 1093 ++ .../superagent/lib/node/parsers/image.js | 10 + .../superagent/lib/node/parsers/index.js | 5 + .../superagent/lib/node/parsers/json.js | 19 + .../superagent/lib/node/parsers/text.js | 7 + .../superagent/lib/node/parsers/urlencoded.js | 19 + .../node_modules/superagent/lib/node/part.js | 149 + .../node_modules/superagent/lib/node/response.js | 210 + .../node_modules/superagent/lib/node/utils.js | 142 + .../node_modules/superagent/lib/request-base.js | 166 + .../node_modules/superagent/lib/request.js | 32 + .../node_modules/component-emitter/History.md | 68 + .../node_modules/component-emitter/LICENSE | 24 + .../node_modules/component-emitter/Readme.md | 74 + .../node_modules/component-emitter/index.js | 163 + .../node_modules/component-emitter/package.json | 181 + .../superagent/node_modules/cookiejar/.npmignore | 1 + .../superagent/node_modules/cookiejar/LICENSE | 9 + .../superagent/node_modules/cookiejar/cookiejar.js | 261 + .../superagent/node_modules/cookiejar/package.json | 53 + .../superagent/node_modules/cookiejar/readme.md | 57 + .../node_modules/cookiejar/tests/test.js | 82 + .../superagent/node_modules/extend/.eslintrc | 192 + .../superagent/node_modules/extend/.jscs.json | 104 + .../superagent/node_modules/extend/.npmignore | 1 + .../superagent/node_modules/extend/.travis.yml | 44 + .../superagent/node_modules/extend/CHANGELOG.md | 69 + .../superagent/node_modules/extend/LICENSE | 23 + .../superagent/node_modules/extend/README.md | 62 + .../superagent/node_modules/extend/component.json | 32 + .../superagent/node_modules/extend/index.js | 86 + .../superagent/node_modules/extend/package.json | 73 + .../superagent/node_modules/form-data/License | 19 + .../superagent/node_modules/form-data/Readme.md | 210 + .../node_modules/form-data/lib/browser.js | 1 + .../node_modules/form-data/lib/form_data.js | 374 + .../form-data/node_modules/async/CHANGELOG.md | 125 + .../form-data/node_modules/async/LICENSE | 19 + .../form-data/node_modules/async/README.md | 1877 +++ .../form-data/node_modules/async/dist/async.js | 1265 ++ .../form-data/node_modules/async/dist/async.min.js | 2 + .../form-data/node_modules/async/lib/async.js | 1265 ++ .../form-data/node_modules/async/package.json | 123 + .../form-data/node_modules/combined-stream/License | 19 + .../node_modules/combined-stream/Readme.md | 138 + .../combined-stream/lib/combined_stream.js | 188 + .../node_modules/delayed-stream/.npmignore | 1 + .../node_modules/delayed-stream/License | 19 + .../node_modules/delayed-stream/Makefile | 7 + .../node_modules/delayed-stream/Readme.md | 141 + .../delayed-stream/lib/delayed_stream.js | 107 + .../node_modules/delayed-stream/package.json | 64 + .../node_modules/combined-stream/package.json | 67 + .../superagent/node_modules/form-data/package.json | 84 + .../superagent/node_modules/formidable/.npmignore | 7 + .../superagent/node_modules/formidable/.travis.yml | 5 + .../superagent/node_modules/formidable/LICENSE | 7 + .../superagent/node_modules/formidable/Readme.md | 425 + .../superagent/node_modules/formidable/index.js | 1 + .../superagent/node_modules/formidable/lib/file.js | 72 + .../node_modules/formidable/lib/incoming_form.js | 555 + .../node_modules/formidable/lib/index.js | 3 + .../node_modules/formidable/lib/json_parser.js | 35 + .../formidable/lib/multipart_parser.js | 332 + .../node_modules/formidable/lib/octet_parser.js | 20 + .../formidable/lib/querystring_parser.js | 27 + .../node_modules/formidable/package.json | 65 + .../superagent/node_modules/qs/.jshintignore | 1 + .../superagent/node_modules/qs/.jshintrc | 10 + .../superagent/node_modules/qs/.npmignore | 18 + .../superagent/node_modules/qs/.travis.yml | 4 + .../superagent/node_modules/qs/CHANGELOG.md | 68 + .../superagent/node_modules/qs/CONTRIBUTING.md | 1 + .../superagent/node_modules/qs/LICENSE | 28 + .../superagent/node_modules/qs/Makefile | 8 + .../superagent/node_modules/qs/README.md | 222 + .../superagent/node_modules/qs/index.js | 1 + .../superagent/node_modules/qs/lib/index.js | 15 + .../superagent/node_modules/qs/lib/parse.js | 157 + .../superagent/node_modules/qs/lib/stringify.js | 77 + .../superagent/node_modules/qs/lib/utils.js | 132 + .../superagent/node_modules/qs/package.json | 58 + .../superagent/node_modules/qs/test/parse.js | 413 + .../superagent/node_modules/qs/test/stringify.js | 179 + .../node_modules/readable-stream/.npmignore | 5 + .../node_modules/readable-stream/LICENSE | 27 + .../node_modules/readable-stream/README.md | 15 + .../node_modules/readable-stream/duplex.js | 1 + .../readable-stream/lib/_stream_duplex.js | 89 + .../readable-stream/lib/_stream_passthrough.js | 46 + .../readable-stream/lib/_stream_readable.js | 959 ++ .../readable-stream/lib/_stream_transform.js | 210 + .../readable-stream/lib/_stream_writable.js | 387 + .../node_modules/readable-stream/package.json | 68 + .../node_modules/readable-stream/passthrough.js | 1 + .../node_modules/readable-stream/readable.js | 6 + .../node_modules/readable-stream/transform.js | 1 + .../node_modules/readable-stream/writable.js | 1 + .../node_modules/reduce-component/.npmignore | 3 + .../node_modules/reduce-component/History.md | 0 .../node_modules/reduce-component/LICENSE | 176 + .../node_modules/reduce-component/Makefile | 16 + .../node_modules/reduce-component/Readme.md | 32 + .../node_modules/reduce-component/component.json | 13 + .../node_modules/reduce-component/index.js | 24 + .../node_modules/reduce-component/package.json | 46 + .../node_modules/reduce-component/test/index.html | 30 + .../node_modules/reduce-component/test/reduce.js | 49 + .../supertest/node_modules/superagent/package.json | 146 + .../node_modules/superagent/superagent.js | 1486 +++ .../supertest/node_modules/superagent/test.js | 6 + node_modules/supertest/package.json | 87 + node_modules/supertest/test/fixtures/test_cert.pem | 16 + node_modules/supertest/test/fixtures/test_key.pem | 15 + node_modules/supertest/test/supertest.js | 1055 ++ 603 files changed, 111780 insertions(+) create mode 120000 node_modules/.bin/_mocha create mode 120000 node_modules/.bin/mocha create mode 100644 node_modules/chai-http/History.md create mode 100644 node_modules/chai-http/dist/chai-http.js create mode 100644 node_modules/chai-http/index.js create mode 100644 node_modules/chai-http/lib/http.js create mode 100644 node_modules/chai-http/lib/net.js create mode 100644 node_modules/chai-http/lib/request.js create mode 100644 node_modules/chai-http/node_modules/cookiejar/.npmignore create mode 100644 node_modules/chai-http/node_modules/cookiejar/LICENSE create mode 100644 node_modules/chai-http/node_modules/cookiejar/cookiejar.js create mode 100644 node_modules/chai-http/node_modules/cookiejar/package.json create mode 100644 node_modules/chai-http/node_modules/cookiejar/readme.md create mode 100755 node_modules/chai-http/node_modules/cookiejar/tests/test.js create mode 100644 node_modules/chai-http/node_modules/is-ip/index.js create mode 100644 node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/index.js create mode 100644 node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/license create mode 100644 node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/package.json create mode 100644 node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/readme.md create mode 100644 node_modules/chai-http/node_modules/is-ip/package.json create mode 100644 node_modules/chai-http/node_modules/is-ip/readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/.npmignore create mode 100644 node_modules/chai-http/node_modules/superagent/.travis.yml create mode 100644 node_modules/chai-http/node_modules/superagent/.zuul.yml create mode 100644 node_modules/chai-http/node_modules/superagent/Contributing.md create mode 100644 node_modules/chai-http/node_modules/superagent/History.md create mode 100644 node_modules/chai-http/node_modules/superagent/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/Makefile create mode 100644 node_modules/chai-http/node_modules/superagent/Readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/component.json create mode 100644 node_modules/chai-http/node_modules/superagent/docs/head.html create mode 100644 node_modules/chai-http/node_modules/superagent/docs/images/bg.png create mode 100644 node_modules/chai-http/node_modules/superagent/docs/index.md create mode 100644 node_modules/chai-http/node_modules/superagent/docs/style.css create mode 100644 node_modules/chai-http/node_modules/superagent/docs/tail.html create mode 100644 node_modules/chai-http/node_modules/superagent/docs/test.html create mode 100644 node_modules/chai-http/node_modules/superagent/lib/client.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/is-object.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/agent.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/parsers/image.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/parsers/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/parsers/json.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/parsers/text.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/parsers/urlencoded.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/part.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/response.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/node/utils.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/request-base.js create mode 100644 node_modules/chai-http/node_modules/superagent/lib/request.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/History.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/Readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/.eslintrc create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/.jscs.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/.npmignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/.travis.yml create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/CHANGELOG.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/README.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/component.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/extend/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/.dockerignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/.editorconfig create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintrc create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/License create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/README.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/browser.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/form_data.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/populate.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/CHANGELOG.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/README.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.min.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/lib/async.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/License create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/Readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/form-data/wercker.yml create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/.npmignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/.travis.yml create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/Readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/file.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/incoming_form.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/json_parser.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/multipart_parser.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/octet_parser.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/lib/querystring_parser.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/formidable/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/.npmignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/.travis.yml create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/README.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/doc/stream.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/duplex.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/buffer-shims/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/buffer-shims/license.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/buffer-shims/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/buffer-shims/readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/.npmignore create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/.travis.yml create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/Makefile create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/README.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/component.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/isarray/test.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/process-nextick-args/.travis.yml create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/process-nextick-args/index.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/process-nextick-args/license.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/process-nextick-args/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/process-nextick-args/readme.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/process-nextick-args/test.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/util-deprecate/History.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/util-deprecate/LICENSE create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/util-deprecate/README.md create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/util-deprecate/browser.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/util-deprecate/node.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/node_modules/util-deprecate/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/readable.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/transform.js create mode 100644 node_modules/chai-http/node_modules/superagent/node_modules/readable-stream/writable.js create mode 100644 node_modules/chai-http/node_modules/superagent/package.json create mode 100644 node_modules/chai-http/node_modules/superagent/superagent.js create mode 100644 node_modules/chai-http/package.json create mode 100644 node_modules/chai/.npmignore create mode 100644 node_modules/chai/CODE_OF_CONDUCT.md create mode 100644 node_modules/chai/CONTRIBUTING.md create mode 100644 node_modules/chai/History.md create mode 100644 node_modules/chai/README.md create mode 100644 node_modules/chai/ReleaseNotes.md create mode 100644 node_modules/chai/bower.json create mode 100644 node_modules/chai/chai.js create mode 100644 node_modules/chai/index.js create mode 100644 node_modules/chai/karma.conf.js create mode 100644 node_modules/chai/karma.sauce.js create mode 100644 node_modules/chai/lib/chai.js create mode 100644 node_modules/chai/lib/chai/assertion.js create mode 100644 node_modules/chai/lib/chai/config.js create mode 100644 node_modules/chai/lib/chai/core/assertions.js create mode 100644 node_modules/chai/lib/chai/interface/assert.js create mode 100644 node_modules/chai/lib/chai/interface/expect.js create mode 100644 node_modules/chai/lib/chai/interface/should.js create mode 100644 node_modules/chai/lib/chai/utils/addChainableMethod.js create mode 100644 node_modules/chai/lib/chai/utils/addMethod.js create mode 100644 node_modules/chai/lib/chai/utils/addProperty.js create mode 100644 node_modules/chai/lib/chai/utils/expectTypes.js create mode 100644 node_modules/chai/lib/chai/utils/flag.js create mode 100644 node_modules/chai/lib/chai/utils/getActual.js create mode 100644 node_modules/chai/lib/chai/utils/getEnumerableProperties.js create mode 100644 node_modules/chai/lib/chai/utils/getMessage.js create mode 100644 node_modules/chai/lib/chai/utils/getName.js create mode 100644 node_modules/chai/lib/chai/utils/getPathInfo.js create mode 100644 node_modules/chai/lib/chai/utils/getPathValue.js create mode 100644 node_modules/chai/lib/chai/utils/getProperties.js create mode 100644 node_modules/chai/lib/chai/utils/hasProperty.js create mode 100644 node_modules/chai/lib/chai/utils/index.js create mode 100644 node_modules/chai/lib/chai/utils/inspect.js create mode 100644 node_modules/chai/lib/chai/utils/objDisplay.js create mode 100644 node_modules/chai/lib/chai/utils/overwriteChainableMethod.js create mode 100644 node_modules/chai/lib/chai/utils/overwriteMethod.js create mode 100644 node_modules/chai/lib/chai/utils/overwriteProperty.js create mode 100644 node_modules/chai/lib/chai/utils/test.js create mode 100644 node_modules/chai/lib/chai/utils/transferFlags.js create mode 100644 node_modules/chai/node_modules/assertion-error/.npmignore create mode 100644 node_modules/chai/node_modules/assertion-error/History.md create mode 100644 node_modules/chai/node_modules/assertion-error/README.md create mode 100644 node_modules/chai/node_modules/assertion-error/index.js create mode 100644 node_modules/chai/node_modules/assertion-error/package.json create mode 100644 node_modules/chai/node_modules/deep-eql/.npmignore create mode 100644 node_modules/chai/node_modules/deep-eql/History.md create mode 100644 node_modules/chai/node_modules/deep-eql/README.md create mode 100644 node_modules/chai/node_modules/deep-eql/index.js create mode 100644 node_modules/chai/node_modules/deep-eql/karma.conf.js create mode 100644 node_modules/chai/node_modules/deep-eql/lib/eql.js create mode 100644 node_modules/chai/node_modules/deep-eql/node_modules/type-detect/.npmignore create mode 100644 node_modules/chai/node_modules/deep-eql/node_modules/type-detect/History.md create mode 100644 node_modules/chai/node_modules/deep-eql/node_modules/type-detect/README.md create mode 100644 node_modules/chai/node_modules/deep-eql/node_modules/type-detect/index.js create mode 100644 node_modules/chai/node_modules/deep-eql/node_modules/type-detect/lib/type.js create mode 100644 node_modules/chai/node_modules/deep-eql/node_modules/type-detect/package.json create mode 100644 node_modules/chai/node_modules/deep-eql/package.json create mode 100644 node_modules/chai/node_modules/type-detect/.npmignore create mode 100644 node_modules/chai/node_modules/type-detect/History.md create mode 100644 node_modules/chai/node_modules/type-detect/README.md create mode 100644 node_modules/chai/node_modules/type-detect/ReleaseNotes.md create mode 100644 node_modules/chai/node_modules/type-detect/index.js create mode 100644 node_modules/chai/node_modules/type-detect/lib/type.js create mode 100644 node_modules/chai/node_modules/type-detect/package.json create mode 100644 node_modules/chai/package.json create mode 100644 node_modules/chai/sauce.browsers.js create mode 100644 node_modules/mocha/CHANGELOG.md create mode 100644 node_modules/mocha/LICENSE create mode 100644 node_modules/mocha/bin/.eslintrc create mode 100755 node_modules/mocha/bin/_mocha create mode 100755 node_modules/mocha/bin/mocha create mode 100644 node_modules/mocha/bin/options.js create mode 100644 node_modules/mocha/images/error.png create mode 100644 node_modules/mocha/images/ok.png create mode 100644 node_modules/mocha/index.js create mode 100644 node_modules/mocha/lib/browser/debug.js create mode 100644 node_modules/mocha/lib/browser/events.js create mode 100644 node_modules/mocha/lib/browser/progress.js create mode 100644 node_modules/mocha/lib/browser/tty.js create mode 100644 node_modules/mocha/lib/context.js create mode 100644 node_modules/mocha/lib/hook.js create mode 100644 node_modules/mocha/lib/interfaces/bdd.js create mode 100644 node_modules/mocha/lib/interfaces/common.js create mode 100644 node_modules/mocha/lib/interfaces/exports.js create mode 100644 node_modules/mocha/lib/interfaces/index.js create mode 100644 node_modules/mocha/lib/interfaces/qunit.js create mode 100644 node_modules/mocha/lib/interfaces/tdd.js create mode 100644 node_modules/mocha/lib/mocha.js create mode 100644 node_modules/mocha/lib/ms.js create mode 100644 node_modules/mocha/lib/pending.js create mode 100644 node_modules/mocha/lib/reporters/base.js create mode 100644 node_modules/mocha/lib/reporters/doc.js create mode 100644 node_modules/mocha/lib/reporters/dot.js create mode 100644 node_modules/mocha/lib/reporters/html-cov.js create mode 100644 node_modules/mocha/lib/reporters/html.js create mode 100644 node_modules/mocha/lib/reporters/index.js create mode 100644 node_modules/mocha/lib/reporters/json-cov.js create mode 100644 node_modules/mocha/lib/reporters/json-stream.js create mode 100644 node_modules/mocha/lib/reporters/json.js create mode 100644 node_modules/mocha/lib/reporters/landing.js create mode 100644 node_modules/mocha/lib/reporters/list.js create mode 100644 node_modules/mocha/lib/reporters/markdown.js create mode 100644 node_modules/mocha/lib/reporters/min.js create mode 100644 node_modules/mocha/lib/reporters/nyan.js create mode 100644 node_modules/mocha/lib/reporters/progress.js create mode 100644 node_modules/mocha/lib/reporters/spec.js create mode 100644 node_modules/mocha/lib/reporters/tap.js create mode 100644 node_modules/mocha/lib/reporters/templates/coverage.jade create mode 100644 node_modules/mocha/lib/reporters/templates/menu.jade create mode 100644 node_modules/mocha/lib/reporters/templates/script.html create mode 100644 node_modules/mocha/lib/reporters/templates/style.html create mode 100644 node_modules/mocha/lib/reporters/xunit.js create mode 100644 node_modules/mocha/lib/runnable.js create mode 100644 node_modules/mocha/lib/runner.js create mode 100644 node_modules/mocha/lib/suite.js create mode 100644 node_modules/mocha/lib/template.html create mode 100644 node_modules/mocha/lib/test.js create mode 100644 node_modules/mocha/lib/utils.js create mode 100644 node_modules/mocha/mocha.css create mode 100644 node_modules/mocha/mocha.js create mode 120000 node_modules/mocha/node_modules/.bin/jade create mode 120000 node_modules/mocha/node_modules/.bin/mkdirp create mode 120000 node_modules/mocha/node_modules/.bin/supports-color create mode 100644 node_modules/mocha/node_modules/commander/Readme.md create mode 100644 node_modules/mocha/node_modules/commander/index.js create mode 100644 node_modules/mocha/node_modules/commander/package.json create mode 100644 node_modules/mocha/node_modules/diff/README.md create mode 100644 node_modules/mocha/node_modules/diff/diff.js create mode 100644 node_modules/mocha/node_modules/diff/package.json create mode 100644 node_modules/mocha/node_modules/escape-string-regexp/index.js create mode 100644 node_modules/mocha/node_modules/escape-string-regexp/package.json create mode 100644 node_modules/mocha/node_modules/escape-string-regexp/readme.md create mode 100644 node_modules/mocha/node_modules/glob/.npmignore create mode 100644 node_modules/mocha/node_modules/glob/.travis.yml create mode 100644 node_modules/mocha/node_modules/glob/LICENSE create mode 100644 node_modules/mocha/node_modules/glob/README.md create mode 100644 node_modules/mocha/node_modules/glob/examples/g.js create mode 100644 node_modules/mocha/node_modules/glob/examples/usr-local.js create mode 100644 node_modules/mocha/node_modules/glob/glob.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/.npmignore create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/LICENSE create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/README.md create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/minimatch.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.travis.yml create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/serialize.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/package.json create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/test/basic.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/test/brace-expand.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/test/caching.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/test/defaults.js create mode 100644 node_modules/mocha/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js create mode 100644 node_modules/mocha/node_modules/glob/package.json create mode 100644 node_modules/mocha/node_modules/glob/test/00-setup.js create mode 100644 node_modules/mocha/node_modules/glob/test/bash-comparison.js create mode 100644 node_modules/mocha/node_modules/glob/test/bash-results.json create mode 100644 node_modules/mocha/node_modules/glob/test/cwd-test.js create mode 100644 node_modules/mocha/node_modules/glob/test/globstar-match.js create mode 100644 node_modules/mocha/node_modules/glob/test/mark.js create mode 100644 node_modules/mocha/node_modules/glob/test/new-glob-optional-options.js create mode 100644 node_modules/mocha/node_modules/glob/test/nocase-nomagic.js create mode 100644 node_modules/mocha/node_modules/glob/test/pause-resume.js create mode 100644 node_modules/mocha/node_modules/glob/test/readme-issue.js create mode 100644 node_modules/mocha/node_modules/glob/test/root-nomount.js create mode 100644 node_modules/mocha/node_modules/glob/test/root.js create mode 100644 node_modules/mocha/node_modules/glob/test/stat.js create mode 100644 node_modules/mocha/node_modules/glob/test/zz-cleanup.js create mode 100644 node_modules/mocha/node_modules/growl/History.md create mode 100644 node_modules/mocha/node_modules/growl/Readme.md create mode 100644 node_modules/mocha/node_modules/growl/lib/growl.js create mode 100644 node_modules/mocha/node_modules/growl/package.json create mode 100644 node_modules/mocha/node_modules/growl/test.js create mode 100644 node_modules/mocha/node_modules/jade/.npmignore create mode 100644 node_modules/mocha/node_modules/jade/LICENSE create mode 100755 node_modules/mocha/node_modules/jade/bin/jade create mode 100644 node_modules/mocha/node_modules/jade/index.js create mode 100644 node_modules/mocha/node_modules/jade/jade.js create mode 100644 node_modules/mocha/node_modules/jade/jade.md create mode 100644 node_modules/mocha/node_modules/jade/jade.min.js create mode 100644 node_modules/mocha/node_modules/jade/lib/compiler.js create mode 100644 node_modules/mocha/node_modules/jade/lib/doctypes.js create mode 100644 node_modules/mocha/node_modules/jade/lib/filters.js create mode 100644 node_modules/mocha/node_modules/jade/lib/inline-tags.js create mode 100644 node_modules/mocha/node_modules/jade/lib/jade.js create mode 100644 node_modules/mocha/node_modules/jade/lib/lexer.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/attrs.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/block.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/case.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/code.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/comment.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/doctype.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/each.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/filter.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/index.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/literal.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/mixin.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/node.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/tag.js create mode 100644 node_modules/mocha/node_modules/jade/lib/nodes/text.js create mode 100644 node_modules/mocha/node_modules/jade/lib/parser.js create mode 100644 node_modules/mocha/node_modules/jade/lib/runtime.js create mode 100644 node_modules/mocha/node_modules/jade/lib/self-closing.js create mode 100644 node_modules/mocha/node_modules/jade/lib/utils.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/.npmignore create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/.travis.yml create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/History.md create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/Makefile create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/Readme.md create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/index.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/lib/commander.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/commander/package.json create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js create mode 100644 node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js create mode 100644 node_modules/mocha/node_modules/jade/package.json create mode 100644 node_modules/mocha/node_modules/jade/runtime.js create mode 100644 node_modules/mocha/node_modules/jade/runtime.min.js create mode 100644 node_modules/mocha/node_modules/jade/test.jade create mode 100644 node_modules/mocha/node_modules/jade/testing/head.jade create mode 100644 node_modules/mocha/node_modules/jade/testing/index.jade create mode 100644 node_modules/mocha/node_modules/jade/testing/index.js create mode 100644 node_modules/mocha/node_modules/jade/testing/layout.jade create mode 100644 node_modules/mocha/node_modules/jade/testing/user.jade create mode 100644 node_modules/mocha/node_modules/jade/testing/user.js create mode 100644 node_modules/mocha/node_modules/mkdirp/.travis.yml create mode 100644 node_modules/mocha/node_modules/mkdirp/LICENSE create mode 100755 node_modules/mocha/node_modules/mkdirp/bin/cmd.js create mode 100644 node_modules/mocha/node_modules/mkdirp/bin/usage.txt create mode 100644 node_modules/mocha/node_modules/mkdirp/examples/pow.js create mode 100644 node_modules/mocha/node_modules/mkdirp/index.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/.travis.yml create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/LICENSE create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/example/parse.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/index.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/package.json create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/readme.markdown create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dash.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/default_bool.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dotted.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/long.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/short.js create mode 100644 node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/whitespace.js create mode 100644 node_modules/mocha/node_modules/mkdirp/package.json create mode 100644 node_modules/mocha/node_modules/mkdirp/readme.markdown create mode 100644 node_modules/mocha/node_modules/mkdirp/test/chmod.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/clobber.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/mkdirp.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/opts_fs.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/opts_fs_sync.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/perm.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/perm_sync.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/race.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/rel.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/return.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/return_sync.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/root.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/sync.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/umask.js create mode 100644 node_modules/mocha/node_modules/mkdirp/test/umask_sync.js create mode 100755 node_modules/mocha/node_modules/supports-color/cli.js create mode 100644 node_modules/mocha/node_modules/supports-color/index.js create mode 100644 node_modules/mocha/node_modules/supports-color/package.json create mode 100644 node_modules/mocha/node_modules/supports-color/readme.md create mode 100644 node_modules/mocha/node_modules/to-iso-string/.npmignore create mode 100644 node_modules/mocha/node_modules/to-iso-string/History.md create mode 100644 node_modules/mocha/node_modules/to-iso-string/Makefile create mode 100644 node_modules/mocha/node_modules/to-iso-string/Readme.md create mode 100644 node_modules/mocha/node_modules/to-iso-string/component.json create mode 100644 node_modules/mocha/node_modules/to-iso-string/index.js create mode 100644 node_modules/mocha/node_modules/to-iso-string/package.json create mode 100644 node_modules/mocha/node_modules/to-iso-string/test/index.js create mode 100644 node_modules/mocha/package.json create mode 100644 node_modules/supertest/.npmignore create mode 100644 node_modules/supertest/.travis.yml create mode 100644 node_modules/supertest/History.md create mode 100644 node_modules/supertest/LICENSE create mode 100644 node_modules/supertest/Readme.md create mode 100644 node_modules/supertest/example.js create mode 100644 node_modules/supertest/index.js create mode 100644 node_modules/supertest/lib/agent.js create mode 100644 node_modules/supertest/lib/test.js create mode 100644 node_modules/supertest/node_modules/superagent/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/.travis.yml create mode 100644 node_modules/supertest/node_modules/superagent/.zuul.yml create mode 100644 node_modules/supertest/node_modules/superagent/Contributing.md create mode 100644 node_modules/supertest/node_modules/superagent/History.md create mode 100644 node_modules/supertest/node_modules/superagent/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/Makefile create mode 100644 node_modules/supertest/node_modules/superagent/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/bower.json create mode 100644 node_modules/supertest/node_modules/superagent/component.json create mode 100644 node_modules/supertest/node_modules/superagent/docs/head.html create mode 100644 node_modules/supertest/node_modules/superagent/docs/highlight.js create mode 100644 node_modules/supertest/node_modules/superagent/docs/images/bg.png create mode 100644 node_modules/supertest/node_modules/superagent/docs/index.md create mode 100644 node_modules/supertest/node_modules/superagent/docs/jquery-ui.min.js create mode 100644 node_modules/supertest/node_modules/superagent/docs/jquery.js create mode 100755 node_modules/supertest/node_modules/superagent/docs/jquery.tocify.min.js create mode 100644 node_modules/supertest/node_modules/superagent/docs/style.css create mode 100644 node_modules/supertest/node_modules/superagent/docs/tail.html create mode 100644 node_modules/supertest/node_modules/superagent/docs/test.html create mode 100644 node_modules/supertest/node_modules/superagent/lib/client.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/is-object.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/agent.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/index.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/parsers/image.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/parsers/index.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/parsers/json.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/parsers/text.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/parsers/urlencoded.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/part.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/response.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/node/utils.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/request-base.js create mode 100644 node_modules/supertest/node_modules/superagent/lib/request.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/component-emitter/History.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/component-emitter/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/component-emitter/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/component-emitter/index.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/component-emitter/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/cookiejar/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/cookiejar/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/cookiejar/cookiejar.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/cookiejar/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/cookiejar/readme.md create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/cookiejar/tests/test.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/.eslintrc create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/.jscs.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/.travis.yml create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/CHANGELOG.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/README.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/component.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/index.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/extend/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/License create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/lib/browser.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/lib/form_data.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/CHANGELOG.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/README.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.min.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/lib/async.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/async/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/License create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Makefile create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/node_modules/combined-stream/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/form-data/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/.travis.yml create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/index.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/file.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/incoming_form.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/index.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/json_parser.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/multipart_parser.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/octet_parser.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/lib/querystring_parser.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/formidable/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/.jshintignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/.jshintrc create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/.travis.yml create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/CHANGELOG.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/CONTRIBUTING.md create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/Makefile create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/README.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/index.js create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/lib/index.js create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/lib/parse.js create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/lib/stringify.js create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/lib/utils.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/qs/package.json create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/test/parse.js create mode 100755 node_modules/supertest/node_modules/superagent/node_modules/qs/test/stringify.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/README.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/duplex.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/lib/_stream_duplex.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/lib/_stream_passthrough.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/lib/_stream_readable.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/lib/_stream_transform.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/lib/_stream_writable.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/passthrough.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/readable.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/transform.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/readable-stream/writable.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/.npmignore create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/History.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/LICENSE create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/Makefile create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/Readme.md create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/component.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/index.js create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/package.json create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/test/index.html create mode 100644 node_modules/supertest/node_modules/superagent/node_modules/reduce-component/test/reduce.js create mode 100644 node_modules/supertest/node_modules/superagent/package.json create mode 100644 node_modules/supertest/node_modules/superagent/superagent.js create mode 100644 node_modules/supertest/node_modules/superagent/test.js create mode 100644 node_modules/supertest/package.json create mode 100644 node_modules/supertest/test/fixtures/test_cert.pem create mode 100644 node_modules/supertest/test/fixtures/test_key.pem create mode 100644 node_modules/supertest/test/supertest.js (limited to 'node_modules') diff --git a/node_modules/.bin/_mocha b/node_modules/.bin/_mocha new file mode 120000 index 0000000..f2a54ff --- /dev/null +++ b/node_modules/.bin/_mocha @@ -0,0 +1 @@ +../mocha/bin/_mocha \ No newline at end of file diff --git a/node_modules/.bin/mocha b/node_modules/.bin/mocha new file mode 120000 index 0000000..43c668d --- /dev/null +++ b/node_modules/.bin/mocha @@ -0,0 +1 @@ +../mocha/bin/mocha \ No newline at end of file diff --git a/node_modules/chai-http/History.md b/node_modules/chai-http/History.md new file mode 100644 index 0000000..513bb23 --- /dev/null +++ b/node_modules/chai-http/History.md @@ -0,0 +1,94 @@ +### Note + +As of 2.0.0, the History.md file has been deprecated. [Please refer to the full +commit logs available on GitHub](https://github.com/chaijs/chai-http/commits/master). + +--- + +1.0.0 / 2014-10-08 +================== + + * update readme + * Merge pull request #14 from keithamus/fix-master + * Fix #13: Convert unroutable addresses to localhost + * Fix #13: Add proper detection of Promise capabilities in tests + * Merge pull request #12 from keithamus/patch-1 + * add travis badge + * add travis support + * Fix typo + * Merge pull request #11 from keithamus/refactor-agent + * (chore) Regenerate README.md + * Add list of contributors to package.json + * Add simple usage docs for request api + * Fix typo in readme + * Add cookie assertions + * Add URL query string parameter assertions + * Add request.agent() which allows persisting of cookies + * Add Promises support + * Listen on random port in tests - not 4000 which may be taken + * Add Test class to exports, to enable extending + * Drastically simplify chai.request() by inheriting superagent + * Update SuperAgent to v0.19.x + * Drop harbor and pauli deps. + +0.5.0 / 2014-08-19 +================== + + * Merge pull request #9 from hurrymaplelad/assert_redirect + * Add redirect assertions + * Merge pull request #8 from lxanders/improveReadme + * Fixed missing word and improved wording in documentation + +0.4.0 / 2013-06-25 +================== + + * support: [readme] cleanup + * Merge pull request #7 from pezra/newer-superagent + * remove previous additions to the history + * bump superagent version dependency + * Merge pull request #5 from wookiehangover/patch-1 + * Fixing typo in Readme + * readme typo + +0.3.0 / 2012-10-24 +================== + + * minor tweak to http docs + * Readme auto generation support + * readme preview + * improve readme code comments + * add readme + * documentation for request api + * update http assertion docs + * add request test for existing url + * support and tests for header existence + * improve type detection error message + * add support for superagent based testing + * code cleanup + * convert to tdd + * clean up test runner + +0.2.0 / 2012-05-15 +================== + + * chai 1.0.0 compatibility + * update package.json + +0.1.0 / 2012-03-10 +================== + + * Merge branch 'refs/heads/dev' + * git/npm ignore + * Add `Asssertion#ip`. + * Docs. + * Add test for Assertion#headers. + * Add test for Assertion#json, Assertion#html Assertion#text. + * Add test for Assertion#header. + * Add test for Assertion#status. + +0.0.1 / 2012-03-06 +================== + + * prepping for release 0.0.1 + * first lib commit + * initial commit diff --git a/node_modules/chai-http/dist/chai-http.js b/node_modules/chai-http/dist/chai-http.js new file mode 100644 index 0000000..f5779ca --- /dev/null +++ b/node_modules/chai-http/dist/chai-http.js @@ -0,0 +1,5309 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.chaiHttp = f()}})(function(){var define,module,exports;return (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 + * MIT Licensed + */ + +/** + * ## Assertions + * + * The Chai HTTP module provides a number of assertions + * for the `expect` and `should` interfaces. + */ + +module.exports = function (chai, _) { + + /*! + * Module dependencies. + */ + + var net = require('net'); + var qs = require('qs'); + var url = require('url'); + var Cookie = require('cookiejar'); + + /*! + * Aliases. + */ + + var Assertion = chai.Assertion + , i = _.inspect; + + /*! + * Expose request builder + */ + + chai.request = require('./request'); + + /*! + * Content types hash. Used to + * define `Assertion` properties. + * + * @type {Object} + */ + + var contentTypes = { + json: 'application/json' + , text: 'text/plain' + , html: 'text/html' + }; + + /*! + * Return a header from `Request` or `Response` object. + * + * @param {Request|Response} object + * @param {String} Header + * @returns {String|Undefined} + */ + + function getHeader(obj, key) { + if (key) key = key.toLowerCase(); + if (obj.getHeader) return obj.getHeader(key); + if (obj.headers) return obj.headers[key]; + }; + + /** + * ### .status (code) + * + * Assert that a response has a supplied status. + * + * ```js + * expect(res).to.have.status(200); + * ``` + * + * @param {Number} status number + * @name status + * @api public + */ + + Assertion.addMethod('status', function (code) { + new Assertion(this._obj).to.have.property('status'); + var status = this._obj.status; + + this.assert( + status == code + , 'expected #{this} to have status code #{exp} but got #{act}' + , 'expected #{this} to not have status code #{act}' + , code + , status + ); + }); + + /** + * ### .header (key[, value]) + * + * Assert that a `Response` or `Request` object has a header. + * If a value is provided, equality to value will be asserted. + * You may also pass a regular expression to check. + * + * __Note:__ When running in a web browser, the + * [same-origin policy](https://tools.ietf.org/html/rfc6454#section-3) + * only allows Chai HTTP to read + * [certain headers](https://www.w3.org/TR/cors/#simple-response-header), + * which can cause assertions to fail. + * + * ```js + * expect(req).to.have.header('x-api-key'); + * expect(req).to.have.header('content-type', 'text/plain'); + * expect(req).to.have.header('content-type', /^text/); + * ``` + * + * @param {String} header key (case insensitive) + * @param {String|RegExp} header value (optional) + * @name header + * @api public + */ + + Assertion.addMethod('header', function (key, value) { + var header = getHeader(this._obj, key); + + if (arguments.length < 2) { + this.assert( + 'undefined' !== typeof header || null === header + , 'expected header \'' + key + '\' to exist' + , 'expected header \'' + key + '\' to not exist' + ); + } else if (arguments[1] instanceof RegExp) { + this.assert( + value.test(header) + , 'expected header \'' + key + '\' to match ' + value + ' but got ' + i(header) + , 'expected header \'' + key + '\' not to match ' + value + ' but got ' + i(header) + , value + , header + ); + } else { + this.assert( + header == value + , 'expected header \'' + key + '\' to have value ' + value + ' but got ' + i(header) + , 'expected header \'' + key + '\' to not have value ' + value + , value + , header + ); + } + }); + + /** + * ### .headers + * + * Assert that a `Response` or `Request` object has headers. + * + * __Note:__ When running in a web browser, the + * [same-origin policy](https://tools.ietf.org/html/rfc6454#section-3) + * only allows Chai HTTP to read + * [certain headers](https://www.w3.org/TR/cors/#simple-response-header), + * which can cause assertions to fail. + * + * ```js + * expect(req).to.have.headers; + * ``` + * + * @name headers + * @api public + */ + + Assertion.addProperty('headers', function () { + this.assert( + this._obj.headers || this._obj.getHeader + , 'expected #{this} to have headers or getHeader method' + , 'expected #{this} to not have headers or getHeader method' + ); + }); + + /** + * ### .ip + * + * Assert that a string represents valid ip address. + * + * ```js + * expect('127.0.0.1').to.be.an.ip; + * expect('2001:0db8:85a3:0000:0000:8a2e:0370:7334').to.be.an.ip; + * ``` + * + * @name ip + * @api public + */ + + Assertion.addProperty('ip', function () { + this.assert( + net.isIP(this._obj) + , 'expected #{this} to be an ip' + , 'expected #{this} to not be an ip' + ); + }); + + /** + * ### .json / .text / .html + * + * Assert that a `Response` or `Request` object has a given content-type. + * + * ```js + * expect(req).to.be.json; + * expect(req).to.be.html; + * expect(req).to.be.text; + * ``` + * + * @name json + * @name html + * @name text + * @api public + */ + + function checkContentType (name) { + var val = contentTypes[name]; + + Assertion.addProperty(name, function () { + new Assertion(this._obj).to.have.headers; + var ct = getHeader(this._obj, 'content-type') + , ins = i(ct) === 'undefined' + ? 'headers' + : i(ct); + + this.assert( + ct && ~ct.indexOf(val) + , 'expected ' + ins + ' to include \'' + val + '\'' + , 'expected ' + ins + ' to not include \'' + val + '\'' + ); + }); + } + + Object + .keys(contentTypes) + .forEach(checkContentType); + + /** + * ### .redirect + * + * Assert that a `Response` object has a redirect status code. + * + * ```js + * expect(res).to.redirect; + * ``` + * + * @name redirect + * @api public + */ + + Assertion.addProperty('redirect', function() { + var redirectCodes = [301, 302, 303] + , status = this._obj.status + , redirects = this._obj.redirects; + + this.assert( + redirectCodes.indexOf(status) >= 0 || redirects && redirects.length + , "expected redirect with 30{1-3} status code but got " + status + , "expected not to redirect but got " + status + " status" + ); + }); + + /** + * ### .redirectTo + * + * Assert that a `Response` object redirects to the supplied location. + * + * ```js + * expect(res).to.redirectTo('http://example.com'); + * ``` + * + * @param {String} location url + * @name redirectTo + * @api public + */ + + Assertion.addMethod('redirectTo', function(destination) { + var redirects = this._obj.redirects; + + new Assertion(this._obj).to.redirect; + + if(redirects && redirects.length) { + this.assert( + redirects.indexOf(destination) > -1 + , 'expected redirect to ' + destination + ' but got ' + redirects.join(' then ') + , 'expected not to redirect to ' + destination + ' but got ' + redirects.join(' then ') + ); + } else { + var assertion = new Assertion(this._obj); + _.transferFlags(this, assertion); + assertion.with.header('location', destination); + } + }); + + /** + * ### .param + * + * Assert that a `Request` object has a query string parameter with a given + * key, (optionally) equal to value + * + * ```js + * expect(req).to.have.param('orderby'); + * expect(req).to.have.param('orderby', 'date'); + * expect(req).to.not.have.param('limit'); + * ``` + * + * @param {String} parameter name + * @param {String} parameter value + * @name param + * @api public + */ + + Assertion.addMethod('param', function(name, value) { + var assertion = new Assertion(); + _.transferFlags(this, assertion); + assertion._obj = qs.parse(url.parse(this._obj.url).query); + assertion.property.apply(assertion, arguments); + }); + + /** + * ### .cookie + * + * Assert that a `Request` or `Response` object has a cookie header with a + * given key, (optionally) equal to value + * + * ```js + * expect(req).to.have.cookie('session_id'); + * expect(req).to.have.cookie('session_id', '1234'); + * expect(req).to.not.have.cookie('PHPSESSID'); + * expect(res).to.have.cookie('session_id'); + * expect(res).to.have.cookie('session_id', '1234'); + * expect(res).to.not.have.cookie('PHPSESSID'); + * ``` + * + * @param {String} parameter name + * @param {String} parameter value + * @name param + * @api public + */ + + Assertion.addMethod('cookie', function (key, value) { + var header = getHeader(this._obj, 'set-cookie') + , cookie; + + if (!header) { + header = (getHeader(this._obj, 'cookie') || '').split(';'); + } + + cookie = Cookie.CookieJar(); + cookie.setCookies(header); + cookie = cookie.getCookie(key, new Cookie.CookieAccessInfo()); + + if (arguments.length === 2) { + this.assert( + cookie.value == value + , 'expected cookie \'' + key + '\' to have value #{exp} but got #{act}' + , 'expected cookie \'' + key + '\' to not have value #{exp}' + , value + , cookie.value + ); + } else { + this.assert( + 'undefined' !== typeof cookie || null === cookie + , 'expected cookie \'' + key + '\' to exist' + , 'expected cookie \'' + key + '\' to not exist' + ); + } + }); +}; + +},{"./request":3,"cookiejar":6,"net":2,"qs":13,"url":25}],2:[function(require,module,exports){ +/*! + * chai-http - request helper + * Copyright(c) 2011-2012 Jake Luer + * MIT Licensed + */ + +/*! + * net.isIP shim for browsers + */ +var isIP = require('is-ip'); + +exports.isIP = isIP; +exports.isIPv4 = isIP.v4; +exports.isIPv6 = isIP.v6; + +},{"is-ip":9}],3:[function(require,module,exports){ +/*! + * chai-http - request helper + * Copyright(c) 2011-2012 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var http = require('http') + , https = require('https') + , methods = require('methods') + , superagent = require('superagent') + , Agent = superagent.agent + , Request = superagent.Request + , util = require('util'); + +/** + * ## Integration Testing + * + * Chai HTTP provides an interface for live integration + * testing via [superagent](https://github.com/visionmedia/superagent). + * To do this, you must first + * construct a request to an application or url. + * + * Upon construction you are provided a chainable api that + * allows you to specify the http VERB request (get, post, etc) + * that you wish to invoke. + * + * #### Application / Server + * + * You may use a function (such as an express or connect app) + * or a node.js http(s) server as the foundation for your request. + * If the server is not running, chai-http will find a suitable + * port to listen on for a given test. + * + * __Note:__ This feature is only supported on Node.js, not in web browsers. + * + * ```js + * chai.request(app) + * .get('/') + * ``` + * + * #### URL + * + * You may also use a base url as the foundation of your request. + * + * ```js + * chai.request('http://localhost:8080') + * .get('/') + * ``` + * + * #### Setting up requests + * + * Once a request is created with a given VERB, it can have headers, form data, + * json, or even file attachments added to it, all with a simple API: + * + * ```js + * // Send some JSON + * chai.request(app) + * .put('/user/me') + * .set('X-API-Key', 'foobar') + * .send({ password: '123', confirmPassword: '123' }) + * ``` + * + * ```js + * // Send some Form Data + * chai.request(app) + * .post('/user/me') + * .field('_method', 'put') + * .field('password', '123') + * .field('confirmPassword', '123') + * ``` + * + * ```js + * // Attach a file + * chai.request(app) + * .post('/user/avatar') + * .attach('imageField', fs.readFileSync('avatar.png'), 'avatar.png') + * ``` + * + * ```js + * // Authenticate with Basic authentication + * chai.request(app) + * .get('/protected') + * .auth('user', 'pass') + * ``` + * + * ```js + * // Chain some GET query parameters + * chai.request(app) + * .get('/search') + * .query({name: 'foo', limit: 10}) // /search?name=foo&limit=10 + * ``` + * + * #### Dealing with the response - traditional + * + * To make the request and assert on its response, the `end` method can be used: + * + * ```js + * chai.request(app) + * .put('/user/me') + * .send({ password: '123', confirmPassword: '123' }) + * .end(function (err, res) { + * expect(err).to.be.null; + * expect(res).to.have.status(200); + * }); + * ``` + * ##### Caveat + * Because the `end` function is passed a callback, assertions are run + * asynchronously. Therefore, a mechanism must be used to notify the testing + * framework that the callback has completed. Otherwise, the test will pass before + * the assertions are checked. + * + * For example, in the [Mocha test framework](http://mochajs.org/), this is + * accomplished using the + * [`done` callback](https://mochajs.org/#asynchronous-code), which signal that the + * callback has completed, and the assertions can be verified: + * + * ```js + * it('fails, as expected', function(done) { // <= Pass in done callback + * chai.request('http://localhost:8080') + * .get('/') + * .end(function(err, res) { + * expect(res).to.have.status(123); + * done(); // <= Call done to signal callback end + * }); + * }) ; + * + * it('succeeds silently!', function() { // <= No done callback + * chai.request('http://localhost:8080') + * .get('/') + * .end(function(err, res) { + * expect(res).to.have.status(123); // <= Test completes before this runs + * }); + * }) ; + * ``` + * + * When `done` is passed in, Mocha will wait until the call to `done()`, or until + * the [timeout](http://mochajs.org/#timeouts) expires. `done` also accepts an + * error parameter when signaling completion. + * + * #### Dealing with the response - Promises + * + * If `Promise` is available, `request()` becomes a Promise capable library - + * and chaining of `then`s becomes possible: + * + * ```js + * chai.request(app) + * .put('/user/me') + * .send({ password: '123', confirmPassword: '123' }) + * .then(function (res) { + * expect(res).to.have.status(200); + * }) + * .catch(function (err) { + * throw err; + * }) + * ``` + * + * __Note:__ Node.js version 0.10.x and some older web browsers do not have + * native promise support. You can use any promise library, such as + * [es6-promise](https://github.com/jakearchibald/es6-promise) or + * [kriskowal/q](https://github.com/kriskowal/q) and call the `addPromise` + * method to use that library with Chai HTTP. For example: + * + * ```js + * var chai = require('chai'); + * chai.use(require('chai-http')); + * + * // Add promise support if this does not exist natively. + * if (!global.Promise) { + * var q = require('q'); + * chai.request.addPromises(q.Promise); + * } + * ``` + * + * #### Retaining cookies with each request + * + * Sometimes you need to keep cookies from one request, and send them with the + * next. For this, `.request.agent()` is available: + * + * ```js + * // Log in + * var agent = chai.request.agent(app) + * agent + * .post('/session') + * .send({ username: 'me', password: '123' }) + * .then(function (res) { + * expect(res).to.have.cookie('sessionid'); + * // The `agent` now has the sessionid cookie saved, and will send it + * // back to the server in the next request: + * return agent.get('/user/me') + * .then(function (res) { + * expect(res).to.have.status(200); + * }) + * }) + * ``` + * + */ + +module.exports = function (app) { + + /*! + * @param {Mixed} function or server + * @returns {Object} API + */ + + var server = ('function' === typeof app) + ? http.createServer(app) + : app + , obj = {}; + + methods.forEach(function (method) { + obj[method] = function (path) { + return new Test(server, method, path); + }; + }); + obj.del = obj.delete; + + return obj; +}; + +module.exports.Test = Test; +module.exports.Request = Test; +module.exports.agent = TestAgent; + +/*! + * Test + * + * An extension of superagent.Request, + * this provides the same chainable api + * as superagent so all things can be modified. + * + * @param {Object|String} server, app, or url + * @param {String} method + * @param {String} path + * @api private + */ + +function Test (app, method, path) { + Request.call(this, method, path); + this.app = app; + this.url = typeof app === 'string' ? app + path : serverAddress(app, path); +} +util.inherits(Test, Request); + +function serverAddress (app, path) { + if ('string' === typeof app) { + return app + path; + } + var addr = app.address(); + if (!addr) { + app.listen(0); + addr = app.address(); + } + var protocol = (app instanceof https.Server) ? 'https' : 'http'; + // If address is "unroutable" IPv4/6 address, then set to localhost + if (addr.address === '0.0.0.0' || addr.address === '::') { + addr.address = '127.0.0.1'; + } + return protocol + '://' + addr.address + ':' + addr.port + path; +} + + +/*! + * agent + * + * Follows the same API as superagent.Request, + * but allows persisting of cookies between requests. + * + * @param {Object|String} server, app, or url + * @param {String} method + * @param {String} path + * @api private + */ + +function TestAgent(app) { + if (!(this instanceof TestAgent)) return new TestAgent(app); + if (typeof app === 'function') app = http.createServer(app); + (Agent || Request).call(this); + this.app = app; +} +util.inherits(TestAgent, Agent || Request); + +// override HTTP verb methods +methods.forEach(function(method){ + TestAgent.prototype[method] = function(url){ + var req = new Test(this.app, method, url) + , self = this; + + if (Agent) { + // When running in Node, cookies are managed via + // `Agent._saveCookies()` and `Agent._attachCookies()`. + req.on('response', function (res) { self._saveCookies(res); }); + req.on('redirect', function (res) { self._saveCookies(res); }); + req.on('redirect', function () { self._attachCookies(req); }); + this._attachCookies(req); + } + else { + // When running in a web browser, cookies are managed via `Request.withCredentials()`. + // The browser will attach cookies based on same-origin policy. + // https://tools.ietf.org/html/rfc6454#section-3 + req.withCredentials(); + } + + return req; + }; +}); + +TestAgent.prototype.del = TestAgent.prototype.delete; + +},{"http":4,"https":4,"methods":10,"superagent":21,"util":28}],4:[function(require,module,exports){ + +},{}],5:[function(require,module,exports){ + +/** + * Expose `Emitter`. + */ + +if (typeof module !== 'undefined') { + module.exports = Emitter; +} + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks['$' + event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +},{}],6:[function(require,module,exports){ +/* jshint node: true */ +(function () { + "use strict"; + + function CookieAccessInfo(domain, path, secure, script) { + if (this instanceof CookieAccessInfo) { + this.domain = domain || undefined; + this.path = path || "/"; + this.secure = !!secure; + this.script = !!script; + return this; + } + return new CookieAccessInfo(domain, path, secure, script); + } + exports.CookieAccessInfo = CookieAccessInfo; + + function Cookie(cookiestr, request_domain, request_path) { + if (cookiestr instanceof Cookie) { + return cookiestr; + } + if (this instanceof Cookie) { + this.name = null; + this.value = null; + this.expiration_date = Infinity; + this.path = String(request_path || "/"); + this.explicit_path = false; + this.domain = request_domain || null; + this.explicit_domain = false; + this.secure = false; //how to define default? + this.noscript = false; //httponly + if (cookiestr) { + this.parse(cookiestr, request_domain, request_path); + } + return this; + } + return new Cookie(cookiestr, request_domain, request_path); + } + exports.Cookie = Cookie; + + Cookie.prototype.toString = function toString() { + var str = [this.name + "=" + this.value]; + if (this.expiration_date !== Infinity) { + str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); + } + if (this.domain) { + str.push("domain=" + this.domain); + } + if (this.path) { + str.push("path=" + this.path); + } + if (this.secure) { + str.push("secure"); + } + if (this.noscript) { + str.push("httponly"); + } + return str.join("; "); + }; + + Cookie.prototype.toValueString = function toValueString() { + return this.name + "=" + this.value; + }; + + var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; + Cookie.prototype.parse = function parse(str, request_domain, request_path) { + if (this instanceof Cookie) { + var parts = str.split(";").filter(function (value) { + return !!value; + }), + pair = parts[0].match(/([^=]+)=([\s\S]*)/), + key = pair[1], + value = pair[2], + i; + this.name = key; + this.value = value; + + for (i = 1; i < parts.length; i += 1) { + pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); + key = pair[1].trim().toLowerCase(); + value = pair[2]; + switch (key) { + case "httponly": + this.noscript = true; + break; + case "expires": + this.expiration_date = value ? + Number(Date.parse(value)) : + Infinity; + break; + case "path": + this.path = value ? + value.trim() : + ""; + this.explicit_path = true; + break; + case "domain": + this.domain = value ? + value.trim() : + ""; + this.explicit_domain = !!this.domain; + break; + case "secure": + this.secure = true; + break; + } + } + + if (!this.explicit_path) { + this.path = request_path || "/"; + } + if (!this.explicit_domain) { + this.domain = request_domain; + } + + return this; + } + return new Cookie().parse(str, request_domain, request_path); + }; + + Cookie.prototype.matches = function matches(access_info) { + if (this.noscript && access_info.script || + this.secure && !access_info.secure || + !this.collidesWith(access_info)) { + return false; + } + return true; + }; + + Cookie.prototype.collidesWith = function collidesWith(access_info) { + if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { + return false; + } + if (this.path && access_info.path.indexOf(this.path) !== 0) { + return false; + } + if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) { + return false; + } + var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); + var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); + if (cookie_domain === access_domain) { + return true; + } + if (cookie_domain) { + if (!this.explicit_domain) { + return false; // we already checked if the domains were exactly the same + } + var wildcard = access_domain.indexOf(cookie_domain); + if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { + return false; + } + return true; + } + return true; + }; + + function CookieJar() { + var cookies, cookies_list, collidable_cookie; + if (this instanceof CookieJar) { + cookies = Object.create(null); //name: [Cookie] + + this.setCookie = function setCookie(cookie, request_domain, request_path) { + var remove, i; + cookie = new Cookie(cookie, request_domain, request_path); + //Delete the cookie if the set is past the current time + remove = cookie.expiration_date <= Date.now(); + if (cookies[cookie.name] !== undefined) { + cookies_list = cookies[cookie.name]; + for (i = 0; i < cookies_list.length; i += 1) { + collidable_cookie = cookies_list[i]; + if (collidable_cookie.collidesWith(cookie)) { + if (remove) { + cookies_list.splice(i, 1); + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + return false; + } + cookies_list[i] = cookie; + return cookie; + } + } + if (remove) { + return false; + } + cookies_list.push(cookie); + return cookie; + } + if (remove) { + return false; + } + cookies[cookie.name] = [cookie]; + return cookies[cookie.name]; + }; + //returns a cookie + this.getCookie = function getCookie(cookie_name, access_info) { + var cookie, i; + cookies_list = cookies[cookie_name]; + if (!cookies_list) { + return; + } + for (i = 0; i < cookies_list.length; i += 1) { + cookie = cookies_list[i]; + if (cookie.expiration_date <= Date.now()) { + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + continue; + } + + if (cookie.matches(access_info)) { + return cookie; + } + } + }; + //returns a list of cookies + this.getCookies = function getCookies(access_info) { + var matches = [], cookie_name, cookie; + for (cookie_name in cookies) { + cookie = this.getCookie(cookie_name, access_info); + if (cookie) { + matches.push(cookie); + } + } + matches.toString = function toString() { + return matches.join(":"); + }; + matches.toValueString = function toValueString() { + return matches.map(function (c) { + return c.toValueString(); + }).join(';'); + }; + return matches; + }; + + return this; + } + return new CookieJar(); + } + exports.CookieJar = CookieJar; + + //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. + CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { + cookies = Array.isArray(cookies) ? + cookies : + cookies.split(cookie_str_splitter); + var successful = [], + i, + cookie; + cookies = cookies.map(function(item){ + return new Cookie(item, request_domain, request_path); + }); + for (i = 0; i < cookies.length; i += 1) { + cookie = cookies[i]; + if (this.setCookie(cookie, request_domain, request_path)) { + successful.push(cookie); + } + } + return successful; + }; +}()); + +},{}],7:[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 + } +} + +},{}],8:[function(require,module,exports){ +'use strict'; + +var v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}'; +var v6 = '(?:(?:[0-9a-fA-F:]){1,4}(?:(?::(?:[0-9a-fA-F]){1,4}|:)){2,7})+'; + +var ip = module.exports = function (opts) { + opts = opts || {}; + return opts.exact ? new RegExp('(?:^' + v4 + '$)|(?:^' + v6 + '$)') : + new RegExp('(?:' + v4 + ')|(?:' + v6 + ')', 'g'); +}; + +ip.v4 = function (opts) { + opts = opts || {}; + return opts.exact ? new RegExp('^' + v4 + '$') : new RegExp(v4, 'g'); +}; + +ip.v6 = function (opts) { + opts = opts || {}; + return opts.exact ? new RegExp('^' + v6 + '$') : new RegExp(v6, 'g'); +}; + +},{}],9:[function(require,module,exports){ +'use strict'; +var ipRegex = require('ip-regex'); + +var ip = module.exports = function (str) { + return ipRegex({exact: true}).test(str); +}; + +ip.v4 = function (str) { + return ipRegex.v4({exact: true}).test(str); +}; + +ip.v6 = function (str) { + return ipRegex.v6({exact: true}).test(str); +}; + +},{"ip-regex":8}],10:[function(require,module,exports){ +/*! + * methods + * Copyright(c) 2013-2014 TJ Holowaychuk + * Copyright(c) 2015-2016 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict'; + +/** + * Module dependencies. + * @private + */ + +var http = require('http'); + +/** + * Module exports. + * @public + */ + +module.exports = getCurrentNodeMethods() || getBasicNodeMethods(); + +/** + * Get the current Node.js methods. + * @private + */ + +function getCurrentNodeMethods() { + return http.METHODS && http.METHODS.map(function lowerCaseMethod(method) { + return method.toLowerCase(); + }); +} + +/** + * Get the "basic" Node.js methods, a snapshot from Node.js 0.10. + * @private + */ + +function getBasicNodeMethods() { + return [ + 'get', + 'post', + 'put', + 'head', + 'delete', + 'options', + 'trace', + 'copy', + 'lock', + 'mkcol', + 'move', + 'purge', + 'propfind', + 'proppatch', + 'unlock', + 'report', + 'mkactivity', + 'checkout', + 'merge', + 'm-search', + 'notify', + 'subscribe', + 'unsubscribe', + 'patch', + 'search', + 'connect' + ]; +} + +},{"http":4}],11:[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; + } + 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); +} + +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); + } +}; + +// 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 = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],12:[function(require,module,exports){ +(function (global){ +/*! https://mths.be/punycode v1.4.0 by @mathias */ +;(function(root) { + + /** Detect free variables */ + var freeExports = typeof exports == 'object' && exports && + !exports.nodeType && exports; + var freeModule = typeof module == 'object' && module && + !module.nodeType && module; + var freeGlobal = typeof global == 'object' && global; + if ( + freeGlobal.global === freeGlobal || + freeGlobal.window === freeGlobal || + freeGlobal.self === freeGlobal + ) { + root = freeGlobal; + } + + /** + * The `punycode` object. + * @name punycode + * @type Object + */ + var punycode, + + /** Highest positive signed 32-bit float value */ + maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 + + /** Bootstring parameters */ + base = 36, + tMin = 1, + tMax = 26, + skew = 38, + damp = 700, + initialBias = 72, + initialN = 128, // 0x80 + delimiter = '-', // '\x2D' + + /** Regular expressions */ + regexPunycode = /^xn--/, + regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars + regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators + + /** Error messages */ + errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' + }, + + /** Convenience shortcuts */ + baseMinusTMin = base - tMin, + floor = Math.floor, + stringFromCharCode = String.fromCharCode, + + /** Temporary variable */ + key; + + /*--------------------------------------------------------------------------*/ + + /** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ + function error(type) { + throw new RangeError(errors[type]); + } + + /** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ + function map(array, fn) { + var length = array.length; + var result = []; + while (length--) { + result[length] = fn(array[length]); + } + return result; + } + + /** + * A simple `Array#map`-like wrapper to work with domain name strings or email + * addresses. + * @private + * @param {String} domain The domain name or email address. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ + function mapDomain(string, fn) { + var parts = string.split('@'); + var result = ''; + if (parts.length > 1) { + // In email addresses, only the domain name should be punycoded. Leave + // the local part (i.e. everything up to `@`) intact. + result = parts[0] + '@'; + string = parts[1]; + } + // Avoid `split(regex)` for IE8 compatibility. See #17. + string = string.replace(regexSeparators, '\x2E'); + var labels = string.split('.'); + var encoded = map(labels, fn).join('.'); + return result + encoded; + } + + /** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ + function ucs2decode(string) { + var output = [], + counter = 0, + length = string.length, + value, + extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + /** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ + function ucs2encode(array) { + return map(array, function(value) { + var output = ''; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + return output; + }).join(''); + } + + /** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ + function basicToDigit(codePoint) { + if (codePoint - 48 < 10) { + return codePoint - 22; + } + if (codePoint - 65 < 26) { + return codePoint - 65; + } + if (codePoint - 97 < 26) { + return codePoint - 97; + } + return base; + } + + /** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ + function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); + } + + /** + * Bias adaptation function as per section 3.4 of RFC 3492. + * https://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ + function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); + } + + /** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ + function decode(input) { + // Don't use UCS-2 + var output = [], + inputLength = input.length, + out, + i = 0, + n = initialN, + bias = initialBias, + basic, + j, + index, + oldi, + w, + k, + digit, + t, + /** Cached calculation results */ + baseMinusT; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base || digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output + output.splice(i++, 0, n); + + } + + return ucs2encode(output); + } + + /** + * Converts a string of Unicode symbols (e.g. a domain name label) to a + * Punycode string of ASCII-only symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ + function encode(input) { + var n, + delta, + handledCPCount, + basicLength, + bias, + j, + m, + q, + k, + t, + currentValue, + output = [], + /** `inputLength` will hold the number of code points in `input`. */ + inputLength, + /** Cached calculation results */ + handledCPCountPlusOne, + baseMinusT, + qMinusT; + + // Convert the input in UCS-2 to Unicode + input = ucs2decode(input); + + // Cache the length + inputLength = input.length; + + // Initialize the state + n = initialN; + delta = 0; + bias = initialBias; + + // Handle the basic code points + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + handledCPCount = basicLength = output.length; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string - if it is not empty - with a delimiter + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + for (m = maxInt, j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow + handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + + if (currentValue == n) { + // Represent delta as a generalized variable-length integer + for (q = delta, k = base; /* no condition */; k += base) { + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + qMinusT = q - t; + baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); + } + + /** + * Converts a Punycode string representing a domain name or an email address + * to Unicode. Only the Punycoded parts of the input will be converted, i.e. + * it doesn't matter if you call it on a string that has already been + * converted to Unicode. + * @memberOf punycode + * @param {String} input The Punycoded domain name or email address to + * convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ + function toUnicode(input) { + return mapDomain(input, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); + } + + /** + * Converts a Unicode string representing a domain name or an email address to + * Punycode. Only the non-ASCII parts of the domain name will be converted, + * i.e. it doesn't matter if you call it with a domain that's already in + * ASCII. + * @memberOf punycode + * @param {String} input The domain name or email address to convert, as a + * Unicode string. + * @returns {String} The Punycode representation of the given domain name or + * email address. + */ + function toASCII(input) { + return mapDomain(input, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); + } + + /*--------------------------------------------------------------------------*/ + + /** Define the public API */ + punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '1.3.2', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode + }; + + /** Expose `punycode` */ + // Some AMD build optimizers, like r.js, check for specific condition patterns + // like the following: + if ( + typeof define == 'function' && + typeof define.amd == 'object' && + define.amd + ) { + define('punycode', function() { + return punycode; + }); + } else if (freeExports && freeModule) { + if (module.exports == freeExports) { + // in Node.js, io.js, or RingoJS v0.8.0+ + freeModule.exports = punycode; + } else { + // in Narwhal or RingoJS v0.7.0- + for (key in punycode) { + punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); + } + } + } else { + // in Rhino or a web browser + root.punycode = punycode; + } + +}(this)); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],13:[function(require,module,exports){ +'use strict'; + +var Stringify = require('./stringify'); +var Parse = require('./parse'); + +module.exports = { + stringify: Stringify, + parse: Parse +}; + +},{"./parse":14,"./stringify":15}],14:[function(require,module,exports){ +'use strict'; + +var Utils = require('./utils'); + +var defaults = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000, + strictNullHandling: false, + plainObjects: false, + allowPrototypes: false, + allowDots: false, + decoder: Utils.decode +}; + +var parseValues = function parseValues(str, options) { + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0; i < parts.length; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[options.decoder(part)] = ''; + + if (options.strictNullHandling) { + obj[options.decoder(part)] = null; + } + } else { + var key = options.decoder(part.slice(0, pos)); + var val = options.decoder(part.slice(pos + 1)); + + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj[key] = [].concat(obj[key]).concat(val); + } else { + obj[key] = val; + } + } + } + + return obj; +}; + +var parseObject = function parseObject(chain, val, options) { + if (!chain.length) { + return val; + } + + var root = chain.shift(); + + var obj; + if (root === '[]') { + obj = []; + obj = obj.concat(parseObject(chain, val, options)); + } else { + obj = options.plainObjects ? Object.create(null) : {}; + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + if ( + !isNaN(index) && + root !== cleanRoot && + String(index) === cleanRoot && + index >= 0 && + (options.parseArrays && index <= options.arrayLimit) + ) { + obj = []; + obj[index] = parseObject(chain, val, options); + } else { + obj[cleanRoot] = parseObject(chain, val, options); + } + } + + return obj; +}; + +var parseKeys = function parseKeys(givenKey, val, options) { + if (!givenKey) { + return; + } + + // Transform dot notation to bracket notation + var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey; + + // The regex chunks + + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; + + // Get the parent + + var segment = parent.exec(key); + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + // If we aren't using plain objects, optionally prefix keys + // that would overwrite object prototype properties + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) { + if (!options.allowPrototypes) { + return; + } + } + + keys.push(segment[1]); + } + + // Loop through children appending to the array until we hit depth + + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { + i += 1; + if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + if (!options.allowPrototypes) { + continue; + } + } + keys.push(segment[1]); + } + + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); + } + + return parseObject(keys, val, options); +}; + +module.exports = function (str, opts) { + var options = opts || {}; + + if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') { + throw new TypeError('Decoder has to be a function.'); + } + + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit; + options.parseArrays = options.parseArrays !== false; + options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder; + options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots; + options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects; + options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit; + options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + + if (str === '' || str === null || typeof str === 'undefined') { + return options.plainObjects ? Object.create(null) : {}; + } + + var tempObj = typeof str === 'string' ? parseValues(str, options) : str; + var obj = options.plainObjects ? Object.create(null) : {}; + + // Iterate over the keys and setup the new object + + var keys = Object.keys(tempObj); + for (var i = 0; i < keys.length; ++i) { + var key = keys[i]; + var newObj = parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj, options); + } + + return Utils.compact(obj); +}; + +},{"./utils":16}],15:[function(require,module,exports){ +'use strict'; + +var Utils = require('./utils'); + +var arrayPrefixGenerators = { + brackets: function brackets(prefix) { + return prefix + '[]'; + }, + indices: function indices(prefix, key) { + return prefix + '[' + key + ']'; + }, + repeat: function repeat(prefix) { + return prefix; + } +}; + +var defaults = { + delimiter: '&', + strictNullHandling: false, + skipNulls: false, + encode: true, + encoder: Utils.encode +}; + +var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) { + var obj = object; + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = obj.toISOString(); + } else if (obj === null) { + if (strictNullHandling) { + return encoder ? encoder(prefix) : prefix; + } + + obj = ''; + } + + if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) { + if (encoder) { + return [encoder(prefix) + '=' + encoder(obj)]; + } + return [prefix + '=' + String(obj)]; + } + + var values = []; + + if (typeof obj === 'undefined') { + return values; + } + + var objKeys; + if (Array.isArray(filter)) { + objKeys = filter; + } else { + var keys = Object.keys(obj); + objKeys = sort ? keys.sort(sort) : keys; + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + if (Array.isArray(obj)) { + values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } else { + values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + } + + return values; +}; + +module.exports = function (object, opts) { + var obj = object; + var options = opts || {}; + var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter; + var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling; + var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls; + var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode; + var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null; + var sort = typeof options.sort === 'function' ? options.sort : null; + var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots; + var objKeys; + var filter; + + if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (Array.isArray(options.filter)) { + objKeys = filter = options.filter; + } + + var keys = []; + + if (typeof obj !== 'object' || obj === null) { + return ''; + } + + var arrayFormat; + if (options.arrayFormat in arrayPrefixGenerators) { + arrayFormat = options.arrayFormat; + } else if ('indices' in options) { + arrayFormat = options.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = 'indices'; + } + + var generateArrayPrefix = arrayPrefixGenerators[arrayFormat]; + + if (!objKeys) { + objKeys = Object.keys(obj); + } + + if (sort) { + objKeys.sort(sort); + } + + for (var i = 0; i < objKeys.length; ++i) { + var key = objKeys[i]; + + if (skipNulls && obj[key] === null) { + continue; + } + + keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots)); + } + + return keys.join(delimiter); +}; + +},{"./utils":16}],16:[function(require,module,exports){ +'use strict'; + +var hexTable = (function () { + var array = new Array(256); + for (var i = 0; i < 256; ++i) { + array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); + } + + return array; +}()); + +exports.arrayToObject = function (source, options) { + var obj = options.plainObjects ? Object.create(null) : {}; + for (var i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; +}; + +exports.merge = function (target, source, options) { + if (!source) { + return target; + } + + if (typeof source !== 'object') { + if (Array.isArray(target)) { + target.push(source); + } else if (typeof target === 'object') { + target[source] = true; + } else { + return [target, source]; + } + + return target; + } + + if (typeof target !== 'object') { + return [target].concat(source); + } + + var mergeTarget = target; + if (Array.isArray(target) && !Array.isArray(source)) { + mergeTarget = exports.arrayToObject(target, options); + } + + return Object.keys(source).reduce(function (acc, key) { + var value = source[key]; + + if (Object.prototype.hasOwnProperty.call(acc, key)) { + acc[key] = exports.merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); +}; + +exports.decode = function (str) { + try { + return decodeURIComponent(str.replace(/\+/g, ' ')); + } catch (e) { + return str; + } +}; + +exports.encode = function (str) { + // This code was originally written by Brian White (mscdex) for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + + var string = typeof str === 'string' ? str : String(str); + + var out = ''; + for (var i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); + + if ( + c === 0x2D || // - + c === 0x2E || // . + c === 0x5F || // _ + c === 0x7E || // ~ + (c >= 0x30 && c <= 0x39) || // 0-9 + (c >= 0x41 && c <= 0x5A) || // a-z + (c >= 0x61 && c <= 0x7A) // A-Z + ) { + out += string.charAt(i); + continue; + } + + if (c < 0x80) { + out = out + hexTable[c]; + continue; + } + + if (c < 0x800) { + out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } + + if (c < 0xD800 || c >= 0xE000) { + out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]); + continue; + } + + i += 1; + c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF)); + out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]; + } + + return out; +}; + +exports.compact = function (obj, references) { + if (typeof obj !== 'object' || obj === null) { + return obj; + } + + var refs = references || []; + var lookup = refs.indexOf(obj); + if (lookup !== -1) { + return refs[lookup]; + } + + refs.push(obj); + + if (Array.isArray(obj)) { + var compacted = []; + + for (var i = 0; i < obj.length; ++i) { + if (obj[i] && typeof obj[i] === 'object') { + compacted.push(exports.compact(obj[i], refs)); + } else if (typeof obj[i] !== 'undefined') { + compacted.push(obj[i]); + } + } + + return compacted; + } + + var keys = Object.keys(obj); + for (var j = 0; j < keys.length; ++j) { + var key = keys[j]; + obj[key] = exports.compact(obj[key], refs); + } + + return obj; +}; + +exports.isRegExp = function (obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +}; + +exports.isBuffer = function (obj) { + if (obj === null || typeof obj === 'undefined') { + return false; + } + + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); +}; + +},{}],17:[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. + +'use strict'; + +// If obj.hasOwnProperty has been overridden, then calling +// obj.hasOwnProperty(prop) will break. +// See: https://github.com/joyent/node/issues/1707 +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +module.exports = function(qs, sep, eq, options) { + sep = sep || '&'; + eq = eq || '='; + var obj = {}; + + if (typeof qs !== 'string' || qs.length === 0) { + return obj; + } + + var regexp = /\+/g; + qs = qs.split(sep); + + var maxKeys = 1000; + if (options && typeof options.maxKeys === 'number') { + maxKeys = options.maxKeys; + } + + var len = qs.length; + // maxKeys <= 0 means that we should not limit keys count + if (maxKeys > 0 && len > maxKeys) { + len = maxKeys; + } + + for (var i = 0; i < len; ++i) { + var x = qs[i].replace(regexp, '%20'), + idx = x.indexOf(eq), + kstr, vstr, k, v; + + if (idx >= 0) { + kstr = x.substr(0, idx); + vstr = x.substr(idx + 1); + } else { + kstr = x; + vstr = ''; + } + + k = decodeURIComponent(kstr); + v = decodeURIComponent(vstr); + + if (!hasOwnProperty(obj, k)) { + obj[k] = v; + } else if (isArray(obj[k])) { + obj[k].push(v); + } else { + obj[k] = [obj[k], v]; + } + } + + return obj; +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +},{}],18:[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. + +'use strict'; + +var stringifyPrimitive = function(v) { + switch (typeof v) { + case 'string': + return v; + + case 'boolean': + return v ? 'true' : 'false'; + + case 'number': + return isFinite(v) ? v : ''; + + default: + return ''; + } +}; + +module.exports = function(obj, sep, eq, name) { + sep = sep || '&'; + eq = eq || '='; + if (obj === null) { + obj = undefined; + } + + if (typeof obj === 'object') { + return map(objectKeys(obj), function(k) { + var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; + if (isArray(obj[k])) { + return map(obj[k], function(v) { + return ks + encodeURIComponent(stringifyPrimitive(v)); + }).join(sep); + } else { + return ks + encodeURIComponent(stringifyPrimitive(obj[k])); + } + }).join(sep); + + } + + if (!name) return ''; + return encodeURIComponent(stringifyPrimitive(name)) + eq + + encodeURIComponent(stringifyPrimitive(obj)); +}; + +var isArray = Array.isArray || function (xs) { + return Object.prototype.toString.call(xs) === '[object Array]'; +}; + +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; +} + +var objectKeys = Object.keys || function (obj) { + var res = []; + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); + } + return res; +}; + +},{}],19:[function(require,module,exports){ +'use strict'; + +exports.decode = exports.parse = require('./decode'); +exports.encode = exports.stringify = require('./encode'); + +},{"./decode":17,"./encode":18}],20:[function(require,module,exports){ + +/** + * Reduce `arr` with `fn`. + * + * @param {Array} arr + * @param {Function} fn + * @param {Mixed} initial + * + * TODO: combatible error handling? + */ + +module.exports = function(arr, fn, initial){ + var idx = 0; + var len = arr.length; + var curr = arguments.length == 3 + ? initial + : arr[idx++]; + + while (idx < len) { + curr = fn.call(null, curr, arr[idx], ++idx, arr); + } + + return curr; +}; +},{}],21:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Emitter = require('emitter'); +var reduce = require('reduce'); +var requestBase = require('./request-base'); +var isObject = require('./is-object'); + +/** + * Root reference for iframes. + */ + +var root; +if (typeof window !== 'undefined') { // Browser window + root = window; +} else if (typeof self !== 'undefined') { // Web Worker + root = self; +} else { // Other environments + root = this; +} + +/** + * Noop. + */ + +function noop(){}; + +/** + * Expose `request`. + */ + +var request = module.exports = require('./request').bind(null, Request); + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + return false; +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pushEncodedKeyValuePair(pairs, key, obj[key]); + } + } + return pairs.join('&'); +} + +/** + * Helps 'serialize' with serializing arrays. + * Mutates the pairs array. + * + * @param {Array} pairs + * @param {String} key + * @param {Mixed} val + */ + +function pushEncodedKeyValuePair(pairs, key, val) { + if (Array.isArray(val)) { + return val.forEach(function(v) { + pushEncodedKeyValuePair(pairs, key, v); + }); + } else if (isObject(val)) { + for(var subkey in val) { + pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); + } + return; + } + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(val)); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var pair; + var pos; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + pos = pair.indexOf('='); + if (pos == -1) { + obj[decodeURIComponent(pair)] = ''; + } else { + obj[decodeURIComponent(pair.slice(0, pos))] = + decodeURIComponent(pair.slice(pos + 1)); + } + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Check if `mime` is json or has +json structured syntax suffix. + * + * @param {String} mime + * @return {Boolean} + * @api private + */ + +function isJSON(mime) { + return /[\/+]json\b/.test(mime); +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return reduce(str.split(/ *; */), function(obj, str){ + var parts = str.split(/ *= */) + , key = parts.shift() + , val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this._setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this._setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this._parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype._setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype._parseBody = function(str){ + var parse = request.parse[this.type]; + if (!parse && isJSON(this.type)) { + parse = request.parse['application/json']; + } + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype._setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = this.statusCode = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; // preserves header name case + this._header = {}; // coerces header names to lowercase + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + // issue #675: return the raw response if the response parsing fails + err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null; + // issue #876: return the http status code if the response parsing fails + err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null; + return self.callback(err); + } + + self.emit('response', res); + + if (err) { + return self.callback(err, res); + } + + try { + if (res.status >= 200 && res.status < 300) { + return self.callback(err, res); + } + + var new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + + self.callback(new_err, res); + } catch(e) { + self.callback(e); // #985 touching res may cause INVALID_STATE_ERR on old Android + } + }); +} + +/** + * Mixin `Emitter` and `requestBase`. + */ + +Emitter(Request.prototype); +for (var key in requestBase) { + Request.prototype[key] = requestBase[key]; +} + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set responseType to `val`. Presently valid responseTypes are 'blob' and + * 'arraybuffer'. + * + * Examples: + * + * req.get('/') + * .responseType('blob') + * .end(callback); + * + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.responseType = function(val){ + this._responseType = val; + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic') + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass, options){ + if (!options) { + options = { + type: 'basic' + } + } + + switch (options.type) { + case 'basic': + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + break; + + case 'auto': + this.username = user; + this.password = pass; + break; + } + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach('content', new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + this._getFormData().append(field, file, filename || file.name); + return this; +}; + +Request.prototype._getFormData = function(){ + if (!this._formData) { + this._formData = new root.FormData(); + } + return this._formData; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); + err.crossDomain = true; + + err.status = this.status; + err.method = this.method; + err.url = this.url; + + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype._timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Compose querystring to append to req.url + * + * @api private + */ + +Request.prototype._appendQueryString = function(){ + var query = this._query.join('&'); + if (query) { + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self._timeoutError(); + if (self._aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + e.direction = 'download'; + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + this._appendQueryString(); + + // initiate request + if (this.username && this.password) { + xhr.open(this.method, this.url, true, this.username, this.password); + } else { + xhr.open(this.method, this.url, true); + } + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { + // serialize stuff + var contentType = this._header['content-type']; + var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; + if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + if (this._responseType) { + xhr.responseType = this._responseType; + } + + // send stuff + this.emit('request', this); + + // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) + // We need null here if data is undefined + xhr.send(typeof data !== 'undefined' ? data : null); + return this; +}; + + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * OPTIONS query to `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.options = function(url, data, fn){ + var req = request('OPTIONS', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} fn + * @return {Request} + * @api public + */ + +function del(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +request['del'] = del; +request['delete'] = del; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} data + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} data or fn + * @param {Function} fn + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +},{"./is-object":22,"./request":24,"./request-base":23,"emitter":5,"reduce":20}],22:[function(require,module,exports){ +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return null !== obj && 'object' === typeof obj; +} + +module.exports = isObject; + +},{}],23:[function(require,module,exports){ +/** + * Module of mixed-in functions shared between node and client code + */ +var isObject = require('./is-object'); + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +exports.clearTimeout = function _clearTimeout(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Override default response body parser + * + * This function will be called to convert incoming data into request.body + * + * @param {Function} + * @api public + */ + +exports.parse = function parse(fn){ + this._parser = fn; + return this; +}; + +/** + * Override default request body serializer + * + * This function will be called to convert data set via .send or .attach into payload to send + * + * @param {Function} + * @api public + */ + +exports.serialize = function serialize(fn){ + this._serializer = fn; + return this; +}; + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +exports.timeout = function timeout(ms){ + this._timeout = ms; + return this; +}; + +/** + * Promise support + * + * @param {Function} resolve + * @param {Function} reject + * @return {Request} + */ + +exports.then = function then(resolve, reject) { + if (!this._fullfilledPromise) { + var self = this; + this._fullfilledPromise = new Promise(function(innerResolve, innerReject){ + self.end(function(err, res){ + if (err) innerReject(err); else innerResolve(res); + }); + }); + } + return this._fullfilledPromise.then(resolve, reject); +} + +/** + * Allow for extension + */ + +exports.use = function use(fn) { + fn(this); + return this; +} + + +/** + * Get request header `field`. + * Case-insensitive. + * + * @param {String} field + * @return {String} + * @api public + */ + +exports.get = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Get case-insensitive header `field` value. + * This is a deprecated internal API. Use `.get(field)` instead. + * + * (getHeader is no longer used internally by the superagent code base) + * + * @param {String} field + * @return {String} + * @api private + * @deprecated + */ + +exports.getHeader = exports.get; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * Case-insensitive. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +exports.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * Case-insensitive. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + */ +exports.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File|Buffer|fs.ReadStream} val + * @return {Request} for chaining + * @api public + */ +exports.field = function(name, val) { + this._getFormData().append(name, val); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ +exports.abort = function(){ + if (this._aborted) { + return this; + } + this._aborted = true; + this.xhr && this.xhr.abort(); // browser + this.req && this.req.abort(); // node + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +exports.withCredentials = function(){ + // This is browser-only functionality. Node side is no-op. + this._withCredentials = true; + return this; +}; + +/** + * Set the max redirects to `n`. Does noting in browser XHR implementation. + * + * @param {Number} n + * @return {Request} for chaining + * @api public + */ + +exports.redirects = function(n){ + this._maxRedirects = n; + return this; +}; + +/** + * Convert to a plain javascript object (not JSON string) of scalar properties. + * Note as this method is designed to return a useful non-this value, + * it cannot be chained. + * + * @return {Object} describing method, url, and data of this request + * @api public + */ + +exports.toJSON = function(){ + return { + method: this.method, + url: this.url, + data: this._data + }; +}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +exports._isHost = function _isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Send `data` as the request body, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}') + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +exports.send = function(data){ + var obj = isObject(data); + var type = this._header['content-type']; + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + // default to x-www-form-urlencoded + if (!type) this.type('form'); + type = this._header['content-type']; + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || this._isHost(data)) return this; + + // default to json + if (!type) this.type('json'); + return this; +}; + +},{"./is-object":22}],24:[function(require,module,exports){ +// The node and browser modules expose versions of this with the +// appropriate constructor function bound as first argument +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(RequestConstructor, method, url) { + // callback + if ('function' == typeof url) { + return new RequestConstructor('GET', method).end(url); + } + + // url first + if (2 == arguments.length) { + return new RequestConstructor('GET', method); + } + + return new RequestConstructor(method, url); +} + +module.exports = request; + +},{}],25:[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. + +'use strict'; + +var punycode = require('punycode'); +var util = require('./util'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; + +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} + +// Reference: RFC 3986, RFC 1808, RFC 2396 + +// define these here so at least they only have to be +// compiled once on the first module load. +var protocolPattern = /^([a-z0-9.+-]+:)/i, + portPattern = /:[0-9]*$/, + + // Special case for a simple path URL + simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/, + + // RFC 2396: characters reserved for delimiting URLs. + // We actually just auto-escape these. + delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'], + + // RFC 2396: characters not allowed for various reasons. + unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims), + + // Allowed by RFCs, but cause of XSS attacks. Always escape these. + autoEscape = ['\''].concat(unwise), + // Characters that are never ever allowed in a hostname. + // Note that any invalid chars are also handled, but these + // are the ones that are *expected* to be seen, so we fast-path + // them. + nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape), + hostEndingChars = ['/', '?', '#'], + hostnameMaxLen = 255, + hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/, + hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/, + // protocols that can allow "unsafe" and "unwise" chars. + unsafeProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that never have a hostname. + hostlessProtocol = { + 'javascript': true, + 'javascript:': true + }, + // protocols that always contain a // bit. + slashedProtocol = { + 'http': true, + 'https': true, + 'ftp': true, + 'gopher': true, + 'file': true, + 'http:': true, + 'https:': true, + 'ftp:': true, + 'gopher:': true, + 'file:': true + }, + querystring = require('querystring'); + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url && util.isObject(url) && url instanceof Url) return url; + + var u = new Url; + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} + +Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) { + if (!util.isString(url)) { + throw new TypeError("Parameter 'url' must be a string, not " + typeof url); + } + + // Copy chrome, IE, opera backslash-handling behavior. + // Back slashes before the query string get converted to forward slashes + // See: https://code.google.com/p/chromium/issues/detail?id=25916 + var queryIndex = url.indexOf('?'), + splitter = + (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#', + uSplit = url.split(splitter), + slashRegex = /\\/g; + uSplit[0] = uSplit[0].replace(slashRegex, '/'); + url = uSplit.join(splitter); + + var rest = url; + + // trim before proceeding. + // This is to support parse stuff like " http://foo.com \n" + rest = rest.trim(); + + if (!slashesDenoteHost && url.split('#').length === 1) { + // Try fast path regexp + var simplePath = simplePathPattern.exec(rest); + if (simplePath) { + this.path = rest; + this.href = rest; + this.pathname = simplePath[1]; + if (simplePath[2]) { + this.search = simplePath[2]; + if (parseQueryString) { + this.query = querystring.parse(this.search.substr(1)); + } else { + this.query = this.search.substr(1); + } + } else if (parseQueryString) { + this.search = ''; + this.query = {}; + } + return this; + } + } + + var proto = protocolPattern.exec(rest); + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.substr(proto.length); + } + + // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) { + var slashes = rest.substr(0, 2) === '//'; + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.substr(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && + (slashes || (proto && !slashedProtocol[proto]))) { + + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:c path:/?@c + + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + + // find the first instance of any hostEndingChars + var hostEnd = -1; + for (var i = 0; i < hostEndingChars.length; i++) { + var hec = rest.indexOf(hostEndingChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + + // at this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + var auth, atSign; + if (hostEnd === -1) { + // atSign can be anywhere. + atSign = rest.lastIndexOf('@'); + } else { + // atSign must be in auth portion. + // http://a@b/c@d => host:b auth:a path:/c@d + atSign = rest.lastIndexOf('@', hostEnd); + } + + // Now we have a portion which is definitely the auth. + // Pull that off. + if (atSign !== -1) { + auth = rest.slice(0, atSign); + rest = rest.slice(atSign + 1); + this.auth = decodeURIComponent(auth); + } + + // the host is the remaining to the left of the first non-host char + hostEnd = -1; + for (var i = 0; i < nonHostChars.length; i++) { + var hec = rest.indexOf(nonHostChars[i]); + if (hec !== -1 && (hostEnd === -1 || hec < hostEnd)) + hostEnd = hec; + } + // if we still have not hit it, then the entire thing is a host. + if (hostEnd === -1) + hostEnd = rest.length; + + this.host = rest.slice(0, hostEnd); + rest = rest.slice(hostEnd); + + // pull out port. + this.parseHost(); + + // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + this.hostname = this.hostname || ''; + + // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + var ipv6Hostname = this.hostname[0] === '[' && + this.hostname[this.hostname.length - 1] === ']'; + + // validate a little. + if (!ipv6Hostname) { + var hostparts = this.hostname.split(/\./); + for (var i = 0, l = hostparts.length; i < l; i++) { + var part = hostparts[i]; + if (!part) continue; + if (!part.match(hostnamePartPattern)) { + var newpart = ''; + for (var j = 0, k = part.length; j < k; j++) { + if (part.charCodeAt(j) > 127) { + // we replace non-ASCII char with a temporary placeholder + // we need this to make sure size of hostname is not + // broken by replacing non-ASCII by nothing + newpart += 'x'; + } else { + newpart += part[j]; + } + } + // we test again with ASCII char only + if (!newpart.match(hostnamePartPattern)) { + var validParts = hostparts.slice(0, i); + var notHost = hostparts.slice(i + 1); + var bit = part.match(hostnamePartStart); + if (bit) { + validParts.push(bit[1]); + notHost.unshift(bit[2]); + } + if (notHost.length) { + rest = '/' + notHost.join('.') + rest; + } + this.hostname = validParts.join('.'); + break; + } + } + } + } + + if (this.hostname.length > hostnameMaxLen) { + this.hostname = ''; + } else { + // hostnames are always lower case. + this.hostname = this.hostname.toLowerCase(); + } + + if (!ipv6Hostname) { + // IDNA Support: Returns a punycoded representation of "domain". + // It only converts parts of the domain name that + // have non-ASCII characters, i.e. it doesn't matter if + // you call it with a domain that already is ASCII-only. + this.hostname = punycode.toASCII(this.hostname); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; + this.href += this.host; + + // strip [ and ] from the hostname + // the host field still retains them, though + if (ipv6Hostname) { + this.hostname = this.hostname.substr(1, this.hostname.length - 2); + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } + + // now rest is set to the post-host stuff. + // chop off any delim chars. + if (!unsafeProtocol[lowerProto]) { + + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + for (var i = 0, l = autoEscape.length; i < l; i++) { + var ae = autoEscape[i]; + if (rest.indexOf(ae) === -1) + continue; + var esc = encodeURIComponent(ae); + if (esc === ae) { + esc = escape(ae); + } + rest = rest.split(ae).join(esc); + } + } + + + // chop off from the tail first. + var hash = rest.indexOf('#'); + if (hash !== -1) { + // got a fragment string. + this.hash = rest.substr(hash); + rest = rest.slice(0, hash); + } + var qm = rest.indexOf('?'); + if (qm !== -1) { + this.search = rest.substr(qm); + this.query = rest.substr(qm + 1); + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + rest = rest.slice(0, qm); + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + if (rest) this.pathname = rest; + if (slashedProtocol[lowerProto] && + this.hostname && !this.pathname) { + this.pathname = '/'; + } + + //to support http.request + if (this.pathname || this.search) { + var p = this.pathname || ''; + var s = this.search || ''; + this.path = p + s; + } + + // finally, reconstruct the href based on what has been validated. + this.href = this.format(); + return this; +}; + +// format a parsed object into a url string +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (util.isString(obj)) obj = urlParse(obj); + if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} + +Url.prototype.format = function() { + var auth = this.auth || ''; + if (auth) { + auth = encodeURIComponent(auth); + auth = auth.replace(/%3A/i, ':'); + auth += '@'; + } + + var protocol = this.protocol || '', + pathname = this.pathname || '', + hash = this.hash || '', + host = false, + query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? + this.hostname : + '[' + this.hostname + ']'); + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query && + util.isObject(this.query) && + Object.keys(this.query).length) { + query = querystring.stringify(this.query); + } + + var search = this.search || (query && ('?' + query)) || ''; + + if (protocol && protocol.substr(-1) !== ':') protocol += ':'; + + // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + if (this.slashes || + (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + if (hash && hash.charAt(0) !== '#') hash = '#' + hash; + if (search && search.charAt(0) !== '?') search = '?' + search; + + pathname = pathname.replace(/[?#]/g, function(match) { + return encodeURIComponent(match); + }); + search = search.replace('#', '%23'); + + return protocol + host + pathname + search + hash; +}; + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} + +Url.prototype.resolve = function(relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} + +Url.prototype.resolveObject = function(relative) { + if (util.isString(relative)) { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + var tkeys = Object.keys(this); + for (var tk = 0; tk < tkeys.length; tk++) { + var tkey = tkeys[tk]; + result[tkey] = this[tkey]; + } + + // hash is always overridden, no matter what. + // even href="" will remove it. + result.hash = relative.hash; + + // if the relative url is empty, then there's nothing left to do here. + if (relative.href === '') { + result.href = result.format(); + return result; + } + + // hrefs like //foo/bar always cut to the protocol. + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + var rkeys = Object.keys(relative); + for (var rk = 0; rk < rkeys.length; rk++) { + var rkey = rkeys[rk]; + if (rkey !== 'protocol') + result[rkey] = relative[rkey]; + } + + //urlParse appends trailing / to urls like http://www.example.com + if (slashedProtocol[result.protocol] && + result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + var keys = Object.keys(relative); + for (var v = 0; v < keys.length; v++) { + var k = keys[v]; + result[k] = relative[k]; + } + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + if (!relative.host && !hostlessProtocol[relative.protocol]) { + var relPath = (relative.pathname || '').split('/'); + while (relPath.length && !(relative.host = relPath.shift())); + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; + // to support http.request + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'), + isRelAbs = ( + relative.host || + relative.pathname && relative.pathname.charAt(0) === '/' + ), + mustEndAbs = (isRelAbs || isSourceAbs || + (result.host && relative.pathname)), + removeAllDots = mustEndAbs, + srcPath = result.pathname && result.pathname.split('/') || [], + relPath = relative.pathname && relative.pathname.split('/') || [], + psychotic = result.protocol && !slashedProtocol[result.protocol]; + + // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + if (psychotic) { + result.hostname = ''; + result.port = null; + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host; + else srcPath.unshift(result.host); + } + result.host = ''; + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host; + else relPath.unshift(relative.host); + } + relative.host = null; + } + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = (relative.host || relative.host === '') ? + relative.host : result.host; + result.hostname = (relative.hostname || relative.hostname === '') ? + relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; + // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (!util.isNullOrUndefined(relative.search)) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); + //occationaly the auth can get stuck only in host + //this especially happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + result.search = relative.search; + result.query = relative.query; + //to support http.request + if (!util.isNull(result.pathname) || !util.isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; + //to support http.request + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + result.href = result.format(); + return result; + } + + // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = ( + (result.host || relative.host || srcPath.length > 1) && + (last === '.' || last === '..') || last === ''); + + // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + var up = 0; + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + if (last === '.') { + srcPath.splice(i, 1); + } else if (last === '..') { + srcPath.splice(i, 1); + up++; + } else if (up) { + srcPath.splice(i, 1); + up--; + } + } + + // if the path is allowed to go above the root, restore leading ..s + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && + (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || + (srcPath[0] && srcPath[0].charAt(0) === '/'); + + // put the host back + if (psychotic) { + result.hostname = result.host = isAbsolute ? '' : + srcPath.length ? srcPath.shift() : ''; + //occationaly the auth can get stuck only in host + //this especially happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + var authInHost = result.host && result.host.indexOf('@') > 0 ? + result.host.split('@') : false; + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || (result.host && srcPath.length); + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } + + //to support request.http + if (!util.isNull(result.pathname) || !util.isNull(result.search)) { + result.path = (result.pathname ? result.pathname : '') + + (result.search ? result.search : ''); + } + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; + +Url.prototype.parseHost = function() { + var host = this.host; + var port = portPattern.exec(host); + if (port) { + port = port[0]; + if (port !== ':') { + this.port = port.substr(1); + } + host = host.substr(0, host.length - port.length); + } + if (host) this.hostname = host; +}; + +},{"./util":26,"punycode":12,"querystring":19}],26:[function(require,module,exports){ +'use strict'; + +module.exports = { + isString: function(arg) { + return typeof(arg) === 'string'; + }, + isObject: function(arg) { + return typeof(arg) === 'object' && arg !== null; + }, + isNull: function(arg) { + return arg === null; + }, + isNullOrUndefined: function(arg) { + return arg == null; + } +}; + +},{}],27:[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'; +} +},{}],28:[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); + } + warned = true; + } + return fn.apply(this, arguments); + } + + 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' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +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; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // 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); + } + + // 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); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + 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); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +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(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +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 (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; +} + + +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); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// 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; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +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; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 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(' '); +} + + +// 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)); +}; + + +/** + * 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; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + 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":27,"_process":11,"inherits":7}]},{},[1])(1) +}); +//# sourceMappingURL=chai-http.js.map diff --git a/node_modules/chai-http/index.js b/node_modules/chai-http/index.js new file mode 100644 index 0000000..b7975ad --- /dev/null +++ b/node_modules/chai-http/index.js @@ -0,0 +1,3 @@ +module.exports = (process && process.env && process.env.CHAIHTTP_COV) + ? require('./lib-cov/http') + : require('./lib/http'); diff --git a/node_modules/chai-http/lib/http.js b/node_modules/chai-http/lib/http.js new file mode 100644 index 0000000..4651443 --- /dev/null +++ b/node_modules/chai-http/lib/http.js @@ -0,0 +1,364 @@ +/*! + * chai-http + * Copyright(c) 2011-2012 Jake Luer + * MIT Licensed + */ + +/** + * ## Assertions + * + * The Chai HTTP module provides a number of assertions + * for the `expect` and `should` interfaces. + */ + +module.exports = function (chai, _) { + + /*! + * Module dependencies. + */ + + var net = require('net'); + var qs = require('qs'); + var url = require('url'); + var Cookie = require('cookiejar'); + + /*! + * Aliases. + */ + + var Assertion = chai.Assertion + , i = _.inspect; + + /*! + * Expose request builder + */ + + chai.request = require('./request'); + + /*! + * Content types hash. Used to + * define `Assertion` properties. + * + * @type {Object} + */ + + var contentTypes = { + json: 'application/json' + , text: 'text/plain' + , html: 'text/html' + }; + + /*! + * Return a header from `Request` or `Response` object. + * + * @param {Request|Response} object + * @param {String} Header + * @returns {String|Undefined} + */ + + function getHeader(obj, key) { + if (key) key = key.toLowerCase(); + if (obj.getHeader) return obj.getHeader(key); + if (obj.headers) return obj.headers[key]; + }; + + /** + * ### .status (code) + * + * Assert that a response has a supplied status. + * + * ```js + * expect(res).to.have.status(200); + * ``` + * + * @param {Number} status number + * @name status + * @api public + */ + + Assertion.addMethod('status', function (code) { + new Assertion(this._obj).to.have.property('status'); + var status = this._obj.status; + + this.assert( + status == code + , 'expected #{this} to have status code #{exp} but got #{act}' + , 'expected #{this} to not have status code #{act}' + , code + , status + ); + }); + + /** + * ### .header (key[, value]) + * + * Assert that a `Response` or `Request` object has a header. + * If a value is provided, equality to value will be asserted. + * You may also pass a regular expression to check. + * + * __Note:__ When running in a web browser, the + * [same-origin policy](https://tools.ietf.org/html/rfc6454#section-3) + * only allows Chai HTTP to read + * [certain headers](https://www.w3.org/TR/cors/#simple-response-header), + * which can cause assertions to fail. + * + * ```js + * expect(req).to.have.header('x-api-key'); + * expect(req).to.have.header('content-type', 'text/plain'); + * expect(req).to.have.header('content-type', /^text/); + * ``` + * + * @param {String} header key (case insensitive) + * @param {String|RegExp} header value (optional) + * @name header + * @api public + */ + + Assertion.addMethod('header', function (key, value) { + var header = getHeader(this._obj, key); + + if (arguments.length < 2) { + this.assert( + 'undefined' !== typeof header || null === header + , 'expected header \'' + key + '\' to exist' + , 'expected header \'' + key + '\' to not exist' + ); + } else if (arguments[1] instanceof RegExp) { + this.assert( + value.test(header) + , 'expected header \'' + key + '\' to match ' + value + ' but got ' + i(header) + , 'expected header \'' + key + '\' not to match ' + value + ' but got ' + i(header) + , value + , header + ); + } else { + this.assert( + header == value + , 'expected header \'' + key + '\' to have value ' + value + ' but got ' + i(header) + , 'expected header \'' + key + '\' to not have value ' + value + , value + , header + ); + } + }); + + /** + * ### .headers + * + * Assert that a `Response` or `Request` object has headers. + * + * __Note:__ When running in a web browser, the + * [same-origin policy](https://tools.ietf.org/html/rfc6454#section-3) + * only allows Chai HTTP to read + * [certain headers](https://www.w3.org/TR/cors/#simple-response-header), + * which can cause assertions to fail. + * + * ```js + * expect(req).to.have.headers; + * ``` + * + * @name headers + * @api public + */ + + Assertion.addProperty('headers', function () { + this.assert( + this._obj.headers || this._obj.getHeader + , 'expected #{this} to have headers or getHeader method' + , 'expected #{this} to not have headers or getHeader method' + ); + }); + + /** + * ### .ip + * + * Assert that a string represents valid ip address. + * + * ```js + * expect('127.0.0.1').to.be.an.ip; + * expect('2001:0db8:85a3:0000:0000:8a2e:0370:7334').to.be.an.ip; + * ``` + * + * @name ip + * @api public + */ + + Assertion.addProperty('ip', function () { + this.assert( + net.isIP(this._obj) + , 'expected #{this} to be an ip' + , 'expected #{this} to not be an ip' + ); + }); + + /** + * ### .json / .text / .html + * + * Assert that a `Response` or `Request` object has a given content-type. + * + * ```js + * expect(req).to.be.json; + * expect(req).to.be.html; + * expect(req).to.be.text; + * ``` + * + * @name json + * @name html + * @name text + * @api public + */ + + function checkContentType (name) { + var val = contentTypes[name]; + + Assertion.addProperty(name, function () { + new Assertion(this._obj).to.have.headers; + var ct = getHeader(this._obj, 'content-type') + , ins = i(ct) === 'undefined' + ? 'headers' + : i(ct); + + this.assert( + ct && ~ct.indexOf(val) + , 'expected ' + ins + ' to include \'' + val + '\'' + , 'expected ' + ins + ' to not include \'' + val + '\'' + ); + }); + } + + Object + .keys(contentTypes) + .forEach(checkContentType); + + /** + * ### .redirect + * + * Assert that a `Response` object has a redirect status code. + * + * ```js + * expect(res).to.redirect; + * ``` + * + * @name redirect + * @api public + */ + + Assertion.addProperty('redirect', function() { + var redirectCodes = [301, 302, 303] + , status = this._obj.status + , redirects = this._obj.redirects; + + this.assert( + redirectCodes.indexOf(status) >= 0 || redirects && redirects.length + , "expected redirect with 30{1-3} status code but got " + status + , "expected not to redirect but got " + status + " status" + ); + }); + + /** + * ### .redirectTo + * + * Assert that a `Response` object redirects to the supplied location. + * + * ```js + * expect(res).to.redirectTo('http://example.com'); + * ``` + * + * @param {String} location url + * @name redirectTo + * @api public + */ + + Assertion.addMethod('redirectTo', function(destination) { + var redirects = this._obj.redirects; + + new Assertion(this._obj).to.redirect; + + if(redirects && redirects.length) { + this.assert( + redirects.indexOf(destination) > -1 + , 'expected redirect to ' + destination + ' but got ' + redirects.join(' then ') + , 'expected not to redirect to ' + destination + ' but got ' + redirects.join(' then ') + ); + } else { + var assertion = new Assertion(this._obj); + _.transferFlags(this, assertion); + assertion.with.header('location', destination); + } + }); + + /** + * ### .param + * + * Assert that a `Request` object has a query string parameter with a given + * key, (optionally) equal to value + * + * ```js + * expect(req).to.have.param('orderby'); + * expect(req).to.have.param('orderby', 'date'); + * expect(req).to.not.have.param('limit'); + * ``` + * + * @param {String} parameter name + * @param {String} parameter value + * @name param + * @api public + */ + + Assertion.addMethod('param', function(name, value) { + var assertion = new Assertion(); + _.transferFlags(this, assertion); + assertion._obj = qs.parse(url.parse(this._obj.url).query); + assertion.property.apply(assertion, arguments); + }); + + /** + * ### .cookie + * + * Assert that a `Request` or `Response` object has a cookie header with a + * given key, (optionally) equal to value + * + * ```js + * expect(req).to.have.cookie('session_id'); + * expect(req).to.have.cookie('session_id', '1234'); + * expect(req).to.not.have.cookie('PHPSESSID'); + * expect(res).to.have.cookie('session_id'); + * expect(res).to.have.cookie('session_id', '1234'); + * expect(res).to.not.have.cookie('PHPSESSID'); + * ``` + * + * @param {String} parameter name + * @param {String} parameter value + * @name param + * @api public + */ + + Assertion.addMethod('cookie', function (key, value) { + var header = getHeader(this._obj, 'set-cookie') + , cookie; + + if (!header) { + header = (getHeader(this._obj, 'cookie') || '').split(';'); + } + + cookie = Cookie.CookieJar(); + cookie.setCookies(header); + cookie = cookie.getCookie(key, new Cookie.CookieAccessInfo()); + + if (arguments.length === 2) { + this.assert( + cookie.value == value + , 'expected cookie \'' + key + '\' to have value #{exp} but got #{act}' + , 'expected cookie \'' + key + '\' to not have value #{exp}' + , value + , cookie.value + ); + } else { + this.assert( + 'undefined' !== typeof cookie || null === cookie + , 'expected cookie \'' + key + '\' to exist' + , 'expected cookie \'' + key + '\' to not exist' + ); + } + }); +}; diff --git a/node_modules/chai-http/lib/net.js b/node_modules/chai-http/lib/net.js new file mode 100644 index 0000000..12fbab8 --- /dev/null +++ b/node_modules/chai-http/lib/net.js @@ -0,0 +1,14 @@ +/*! + * chai-http - request helper + * Copyright(c) 2011-2012 Jake Luer + * MIT Licensed + */ + +/*! + * net.isIP shim for browsers + */ +var isIP = require('is-ip'); + +exports.isIP = isIP; +exports.isIPv4 = isIP.v4; +exports.isIPv6 = isIP.v6; diff --git a/node_modules/chai-http/lib/request.js b/node_modules/chai-http/lib/request.js new file mode 100644 index 0000000..fa583de --- /dev/null +++ b/node_modules/chai-http/lib/request.js @@ -0,0 +1,311 @@ +/*! + * chai-http - request helper + * Copyright(c) 2011-2012 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependancies + */ + +var http = require('http') + , https = require('https') + , methods = require('methods') + , superagent = require('superagent') + , Agent = superagent.agent + , Request = superagent.Request + , util = require('util'); + +/** + * ## Integration Testing + * + * Chai HTTP provides an interface for live integration + * testing via [superagent](https://github.com/visionmedia/superagent). + * To do this, you must first + * construct a request to an application or url. + * + * Upon construction you are provided a chainable api that + * allows you to specify the http VERB request (get, post, etc) + * that you wish to invoke. + * + * #### Application / Server + * + * You may use a function (such as an express or connect app) + * or a node.js http(s) server as the foundation for your request. + * If the server is not running, chai-http will find a suitable + * port to listen on for a given test. + * + * __Note:__ This feature is only supported on Node.js, not in web browsers. + * + * ```js + * chai.request(app) + * .get('/') + * ``` + * + * #### URL + * + * You may also use a base url as the foundation of your request. + * + * ```js + * chai.request('http://localhost:8080') + * .get('/') + * ``` + * + * #### Setting up requests + * + * Once a request is created with a given VERB, it can have headers, form data, + * json, or even file attachments added to it, all with a simple API: + * + * ```js + * // Send some JSON + * chai.request(app) + * .put('/user/me') + * .set('X-API-Key', 'foobar') + * .send({ password: '123', confirmPassword: '123' }) + * ``` + * + * ```js + * // Send some Form Data + * chai.request(app) + * .post('/user/me') + * .field('_method', 'put') + * .field('password', '123') + * .field('confirmPassword', '123') + * ``` + * + * ```js + * // Attach a file + * chai.request(app) + * .post('/user/avatar') + * .attach('imageField', fs.readFileSync('avatar.png'), 'avatar.png') + * ``` + * + * ```js + * // Authenticate with Basic authentication + * chai.request(app) + * .get('/protected') + * .auth('user', 'pass') + * ``` + * + * ```js + * // Chain some GET query parameters + * chai.request(app) + * .get('/search') + * .query({name: 'foo', limit: 10}) // /search?name=foo&limit=10 + * ``` + * + * #### Dealing with the response - traditional + * + * To make the request and assert on its response, the `end` method can be used: + * + * ```js + * chai.request(app) + * .put('/user/me') + * .send({ password: '123', confirmPassword: '123' }) + * .end(function (err, res) { + * expect(err).to.be.null; + * expect(res).to.have.status(200); + * }); + * ``` + * ##### Caveat + * Because the `end` function is passed a callback, assertions are run + * asynchronously. Therefore, a mechanism must be used to notify the testing + * framework that the callback has completed. Otherwise, the test will pass before + * the assertions are checked. + * + * For example, in the [Mocha test framework](http://mochajs.org/), this is + * accomplished using the + * [`done` callback](https://mochajs.org/#asynchronous-code), which signal that the + * callback has completed, and the assertions can be verified: + * + * ```js + * it('fails, as expected', function(done) { // <= Pass in done callback + * chai.request('http://localhost:8080') + * .get('/') + * .end(function(err, res) { + * expect(res).to.have.status(123); + * done(); // <= Call done to signal callback end + * }); + * }) ; + * + * it('succeeds silently!', function() { // <= No done callback + * chai.request('http://localhost:8080') + * .get('/') + * .end(function(err, res) { + * expect(res).to.have.status(123); // <= Test completes before this runs + * }); + * }) ; + * ``` + * + * When `done` is passed in, Mocha will wait until the call to `done()`, or until + * the [timeout](http://mochajs.org/#timeouts) expires. `done` also accepts an + * error parameter when signaling completion. + * + * #### Dealing with the response - Promises + * + * If `Promise` is available, `request()` becomes a Promise capable library - + * and chaining of `then`s becomes possible: + * + * ```js + * chai.request(app) + * .put('/user/me') + * .send({ password: '123', confirmPassword: '123' }) + * .then(function (res) { + * expect(res).to.have.status(200); + * }) + * .catch(function (err) { + * throw err; + * }) + * ``` + * + * __Note:__ Node.js version 0.10.x and some older web browsers do not have + * native promise support. You can use any promise library, such as + * [es6-promise](https://github.com/jakearchibald/es6-promise) or + * [kriskowal/q](https://github.com/kriskowal/q) and call the `addPromise` + * method to use that library with Chai HTTP. For example: + * + * ```js + * var chai = require('chai'); + * chai.use(require('chai-http')); + * + * // Add promise support if this does not exist natively. + * if (!global.Promise) { + * var q = require('q'); + * chai.request.addPromises(q.Promise); + * } + * ``` + * + * #### Retaining cookies with each request + * + * Sometimes you need to keep cookies from one request, and send them with the + * next. For this, `.request.agent()` is available: + * + * ```js + * // Log in + * var agent = chai.request.agent(app) + * agent + * .post('/session') + * .send({ username: 'me', password: '123' }) + * .then(function (res) { + * expect(res).to.have.cookie('sessionid'); + * // The `agent` now has the sessionid cookie saved, and will send it + * // back to the server in the next request: + * return agent.get('/user/me') + * .then(function (res) { + * expect(res).to.have.status(200); + * }) + * }) + * ``` + * + */ + +module.exports = function (app) { + + /*! + * @param {Mixed} function or server + * @returns {Object} API + */ + + var server = ('function' === typeof app) + ? http.createServer(app) + : app + , obj = {}; + + methods.forEach(function (method) { + obj[method] = function (path) { + return new Test(server, method, path); + }; + }); + obj.del = obj.delete; + + return obj; +}; + +module.exports.Test = Test; +module.exports.Request = Test; +module.exports.agent = TestAgent; + +/*! + * Test + * + * An extension of superagent.Request, + * this provides the same chainable api + * as superagent so all things can be modified. + * + * @param {Object|String} server, app, or url + * @param {String} method + * @param {String} path + * @api private + */ + +function Test (app, method, path) { + Request.call(this, method, path); + this.app = app; + this.url = typeof app === 'string' ? app + path : serverAddress(app, path); +} +util.inherits(Test, Request); + +function serverAddress (app, path) { + if ('string' === typeof app) { + return app + path; + } + var addr = app.address(); + if (!addr) { + app.listen(0); + addr = app.address(); + } + var protocol = (app instanceof https.Server) ? 'https' : 'http'; + // If address is "unroutable" IPv4/6 address, then set to localhost + if (addr.address === '0.0.0.0' || addr.address === '::') { + addr.address = '127.0.0.1'; + } + return protocol + '://' + addr.address + ':' + addr.port + path; +} + + +/*! + * agent + * + * Follows the same API as superagent.Request, + * but allows persisting of cookies between requests. + * + * @param {Object|String} server, app, or url + * @param {String} method + * @param {String} path + * @api private + */ + +function TestAgent(app) { + if (!(this instanceof TestAgent)) return new TestAgent(app); + if (typeof app === 'function') app = http.createServer(app); + (Agent || Request).call(this); + this.app = app; +} +util.inherits(TestAgent, Agent || Request); + +// override HTTP verb methods +methods.forEach(function(method){ + TestAgent.prototype[method] = function(url){ + var req = new Test(this.app, method, url) + , self = this; + + if (Agent) { + // When running in Node, cookies are managed via + // `Agent._saveCookies()` and `Agent._attachCookies()`. + req.on('response', function (res) { self._saveCookies(res); }); + req.on('redirect', function (res) { self._saveCookies(res); }); + req.on('redirect', function () { self._attachCookies(req); }); + this._attachCookies(req); + } + else { + // When running in a web browser, cookies are managed via `Request.withCredentials()`. + // The browser will attach cookies based on same-origin policy. + // https://tools.ietf.org/html/rfc6454#section-3 + req.withCredentials(); + } + + return req; + }; +}); + +TestAgent.prototype.del = TestAgent.prototype.delete; diff --git a/node_modules/chai-http/node_modules/cookiejar/.npmignore b/node_modules/chai-http/node_modules/cookiejar/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/chai-http/node_modules/cookiejar/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/chai-http/node_modules/cookiejar/LICENSE b/node_modules/chai-http/node_modules/cookiejar/LICENSE new file mode 100644 index 0000000..58a23ec --- /dev/null +++ b/node_modules/chai-http/node_modules/cookiejar/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) +Copyright (c) 2013 Bradley Meck + +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. + diff --git a/node_modules/chai-http/node_modules/cookiejar/cookiejar.js b/node_modules/chai-http/node_modules/cookiejar/cookiejar.js new file mode 100644 index 0000000..ed1e02e --- /dev/null +++ b/node_modules/chai-http/node_modules/cookiejar/cookiejar.js @@ -0,0 +1,261 @@ +/* jshint node: true */ +(function () { + "use strict"; + + function CookieAccessInfo(domain, path, secure, script) { + if (this instanceof CookieAccessInfo) { + this.domain = domain || undefined; + this.path = path || "/"; + this.secure = !!secure; + this.script = !!script; + return this; + } + return new CookieAccessInfo(domain, path, secure, script); + } + exports.CookieAccessInfo = CookieAccessInfo; + + function Cookie(cookiestr, request_domain, request_path) { + if (cookiestr instanceof Cookie) { + return cookiestr; + } + if (this instanceof Cookie) { + this.name = null; + this.value = null; + this.expiration_date = Infinity; + this.path = String(request_path || "/"); + this.explicit_path = false; + this.domain = request_domain || null; + this.explicit_domain = false; + this.secure = false; //how to define default? + this.noscript = false; //httponly + if (cookiestr) { + this.parse(cookiestr, request_domain, request_path); + } + return this; + } + return new Cookie(cookiestr, request_domain, request_path); + } + exports.Cookie = Cookie; + + Cookie.prototype.toString = function toString() { + var str = [this.name + "=" + this.value]; + if (this.expiration_date !== Infinity) { + str.push("expires=" + (new Date(this.expiration_date)).toGMTString()); + } + if (this.domain) { + str.push("domain=" + this.domain); + } + if (this.path) { + str.push("path=" + this.path); + } + if (this.secure) { + str.push("secure"); + } + if (this.noscript) { + str.push("httponly"); + } + return str.join("; "); + }; + + Cookie.prototype.toValueString = function toValueString() { + return this.name + "=" + this.value; + }; + + var cookie_str_splitter = /[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g; + Cookie.prototype.parse = function parse(str, request_domain, request_path) { + if (this instanceof Cookie) { + var parts = str.split(";").filter(function (value) { + return !!value; + }), + pair = parts[0].match(/([^=]+)=([\s\S]*)/), + key = pair[1], + value = pair[2], + i; + this.name = key; + this.value = value; + + for (i = 1; i < parts.length; i += 1) { + pair = parts[i].match(/([^=]+)(?:=([\s\S]*))?/); + key = pair[1].trim().toLowerCase(); + value = pair[2]; + switch (key) { + case "httponly": + this.noscript = true; + break; + case "expires": + this.expiration_date = value ? + Number(Date.parse(value)) : + Infinity; + break; + case "path": + this.path = value ? + value.trim() : + ""; + this.explicit_path = true; + break; + case "domain": + this.domain = value ? + value.trim() : + ""; + this.explicit_domain = !!this.domain; + break; + case "secure": + this.secure = true; + break; + } + } + + if (!this.explicit_path) { + this.path = request_path || "/"; + } + if (!this.explicit_domain) { + this.domain = request_domain; + } + + return this; + } + return new Cookie().parse(str, request_domain, request_path); + }; + + Cookie.prototype.matches = function matches(access_info) { + if (this.noscript && access_info.script || + this.secure && !access_info.secure || + !this.collidesWith(access_info)) { + return false; + } + return true; + }; + + Cookie.prototype.collidesWith = function collidesWith(access_info) { + if ((this.path && !access_info.path) || (this.domain && !access_info.domain)) { + return false; + } + if (this.path && access_info.path.indexOf(this.path) !== 0) { + return false; + } + if (this.explicit_path && access_info.path.indexOf( this.path ) !== 0) { + return false; + } + var access_domain = access_info.domain && access_info.domain.replace(/^[\.]/,''); + var cookie_domain = this.domain && this.domain.replace(/^[\.]/,''); + if (cookie_domain === access_domain) { + return true; + } + if (cookie_domain) { + if (!this.explicit_domain) { + return false; // we already checked if the domains were exactly the same + } + var wildcard = access_domain.indexOf(cookie_domain); + if (wildcard === -1 || wildcard !== access_domain.length - cookie_domain.length) { + return false; + } + return true; + } + return true; + }; + + function CookieJar() { + var cookies, cookies_list, collidable_cookie; + if (this instanceof CookieJar) { + cookies = Object.create(null); //name: [Cookie] + + this.setCookie = function setCookie(cookie, request_domain, request_path) { + var remove, i; + cookie = new Cookie(cookie, request_domain, request_path); + //Delete the cookie if the set is past the current time + remove = cookie.expiration_date <= Date.now(); + if (cookies[cookie.name] !== undefined) { + cookies_list = cookies[cookie.name]; + for (i = 0; i < cookies_list.length; i += 1) { + collidable_cookie = cookies_list[i]; + if (collidable_cookie.collidesWith(cookie)) { + if (remove) { + cookies_list.splice(i, 1); + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + return false; + } + cookies_list[i] = cookie; + return cookie; + } + } + if (remove) { + return false; + } + cookies_list.push(cookie); + return cookie; + } + if (remove) { + return false; + } + cookies[cookie.name] = [cookie]; + return cookies[cookie.name]; + }; + //returns a cookie + this.getCookie = function getCookie(cookie_name, access_info) { + var cookie, i; + cookies_list = cookies[cookie_name]; + if (!cookies_list) { + return; + } + for (i = 0; i < cookies_list.length; i += 1) { + cookie = cookies_list[i]; + if (cookie.expiration_date <= Date.now()) { + if (cookies_list.length === 0) { + delete cookies[cookie.name]; + } + continue; + } + + if (cookie.matches(access_info)) { + return cookie; + } + } + }; + //returns a list of cookies + this.getCookies = function getCookies(access_info) { + var matches = [], cookie_name, cookie; + for (cookie_name in cookies) { + cookie = this.getCookie(cookie_name, access_info); + if (cookie) { + matches.push(cookie); + } + } + matches.toString = function toString() { + return matches.join(":"); + }; + matches.toValueString = function toValueString() { + return matches.map(function (c) { + return c.toValueString(); + }).join(';'); + }; + return matches; + }; + + return this; + } + return new CookieJar(); + } + exports.CookieJar = CookieJar; + + //returns list of cookies that were set correctly. Cookies that are expired and removed are not returned. + CookieJar.prototype.setCookies = function setCookies(cookies, request_domain, request_path) { + cookies = Array.isArray(cookies) ? + cookies : + cookies.split(cookie_str_splitter); + var successful = [], + i, + cookie; + cookies = cookies.map(function(item){ + return new Cookie(item, request_domain, request_path); + }); + for (i = 0; i < cookies.length; i += 1) { + cookie = cookies[i]; + if (this.setCookie(cookie, request_domain, request_path)) { + successful.push(cookie); + } + } + return successful; + }; +}()); diff --git a/node_modules/chai-http/node_modules/cookiejar/package.json b/node_modules/chai-http/node_modules/cookiejar/package.json new file mode 100644 index 0000000..410eed9 --- /dev/null +++ b/node_modules/chai-http/node_modules/cookiejar/package.json @@ -0,0 +1,54 @@ +{ + "name": "cookiejar", + "version": "2.0.6", + "author": { + "name": "bradleymeck" + }, + "main": "cookiejar.js", + "description": "simple persistent cookiejar system", + "license": "MIT", + "jshintConfig": { + "node": true + }, + "scripts": { + "test": "node tests/test.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bmeck/node-cookiejar.git" + }, + "devDependencies": { + "jshint": "^2.8.0" + }, + "gitHead": "3c3d43c39dc3c6928354873d43f3ec2895e26937", + "bugs": { + "url": "https://github.com/bmeck/node-cookiejar/issues" + }, + "homepage": "https://github.com/bmeck/node-cookiejar#readme", + "_id": "cookiejar@2.0.6", + "_shasum": "0abf356ad00d1c5a219d88d44518046dd026acfe", + "_from": "cookiejar@>=2.0.0 <2.1.0", + "_npmVersion": "3.3.12", + "_nodeVersion": "6.0.0-pre", + "_npmUser": { + "name": "bradleymeck", + "email": "bradley.meck@gmail.com" + }, + "dist": { + "shasum": "0abf356ad00d1c5a219d88d44518046dd026acfe", + "tarball": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz" + }, + "maintainers": [ + { + "name": "andyburke", + "email": "aburke@bitflood.org" + }, + { + "name": "bradleymeck", + "email": "bradley.meck@gmail.com" + } + ], + "directories": {}, + "_resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.0.6.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/chai-http/node_modules/cookiejar/readme.md b/node_modules/chai-http/node_modules/cookiejar/readme.md new file mode 100644 index 0000000..3d39ec6 --- /dev/null +++ b/node_modules/chai-http/node_modules/cookiejar/readme.md @@ -0,0 +1,57 @@ +#CookieJar + +Simple robust cookie library + +##Exports + +###CookieAccessInfo(domain,path,secure,script) + + class to determine matching qualities of a cookie + +#####Properties + +* String domain - domain to match +* String path - path to match +* Boolean secure - access is secure (ssl generally) +* Boolean script - access is from a script + + +###Cookie(cookiestr_or_cookie, request_domain, request_path) + + turns input into a Cookie (singleton if given a Cookie) + the `request_domain` argument is used to default the domain if it is not explicit in the cookie string + the `request_path` argument is used to set the path if it is not explicit in a cookie String. + + explicit domains/paths will cascade, implied domains/paths must *exactly* match (see http://en.wikipedia.org/wiki/HTTP_cookie#Domain_and_Pat) + +#####Properties + +* String name - name of the cookie +* String value - string associated with the cookie +* String domain - domain to match (on a cookie a '.' at the start means a wildcard matching anything ending in the rest) +* Boolean explicit_domain - if the domain was explicitly set via the cookie string +* String path - base path to match (matches any path starting with this '/' is root) +* Boolean explicit_path - if the path was explicitly set via the cookie string +* Boolean noscript - if it should be kept from scripts +* Boolean secure - should it only be transmitted over secure means +* Number expiration_date - number of millis since 1970 at which this should be removed + +#####Methods + +* String toString() - the __set-cookie:__ string for this cookie +* String toValueString() - the __cookie:__ string for this cookie +* Cookie parse(cookiestr, request_domain, request_path) - parses the string onto this cookie or a new one if called directly +* Boolean matches(access_info) - returns true if the access_info allows retrieval of this cookie +* Boolean collidesWith(cookie) - returns true if the cookies cannot exist in the same space (domain and path match) + + +###CookieJar() + + class to hold numerous cookies from multiple domains correctly + +#####Methods + +* Cookie setCookie(cookie, request_domain, request_path) - add a cookie to the jar +* Cookie[] setCookies(cookiestr_or_list, request_domain, request_path) - add a large number of cookies to the jar +* Cookie getCookie(cookie_name,access_info) - get a cookie with the name and access_info matching +* Cookie[] getCookies(access_info) - grab all cookies matching this access_info diff --git a/node_modules/chai-http/node_modules/cookiejar/tests/test.js b/node_modules/chai-http/node_modules/cookiejar/tests/test.js new file mode 100755 index 0000000..80e70f1 --- /dev/null +++ b/node_modules/chai-http/node_modules/cookiejar/tests/test.js @@ -0,0 +1,82 @@ +#!/usr/bin/env node +var Cookie=require("../cookiejar"), + CookieAccessInfo = Cookie.CookieAccessInfo, + CookieJar = Cookie.CookieJar, + Cookie = Cookie.Cookie; + +var assert = require('assert'); + +// Test Cookie +var cookie = new Cookie("a=1;domain=.test.com;path=/"); +assert.equal(cookie.name, "a"); +assert.equal(cookie.value, "1"); +assert.equal(cookie.domain, ".test.com"); +assert.equal(cookie.path, "/"); +assert.equal(cookie.secure, false); +assert.equal(cookie.expiration_date, Infinity); + +assert.deepEqual(cookie, new Cookie("a=1;domain=.test.com;path=/")); +assert.ok(cookie.collidesWith(new Cookie("a=1;domain=.test.com;path=/"))); + +var cookie = new Cookie("a=1;path=/", ".test.com"); +assert.equal(cookie.domain, ".test.com"); + + +// Test CookieJar +var test_jar = CookieJar(); +test_jar.setCookies( + "a=1;domain=.test.com;path=/" + +":b=2;domain=test.com;path=/" + +":c=3;domain=test.com;path=/;expires=January 1, 1970"); +var cookies=test_jar.getCookies(CookieAccessInfo("test.com","/")) +assert.equal(cookies.length, 2, "Expires on setCookies fail\n" + cookies.toString()); +assert.equal(cookies.toValueString(), 'a=1;b=2', "Cannot get value string of multiple cookies"); + +cookies=test_jar.getCookies(CookieAccessInfo("www.test.com","/")) +assert.equal(cookies.length, 2, "Wildcard domain fail\n" + cookies.toString()); + +test_jar.setCookies("b=2;domain=test.com;path=/;expires=January 1, 1970"); +cookies=test_jar.getCookies(CookieAccessInfo("test.com","/")) +assert.equal(cookies.length, 1, "Delete cookie fail\n" + cookies.toString()); +assert.equal(String(test_jar.getCookies(CookieAccessInfo("test.com","/"))), "a=1; domain=.test.com; path=/"); + +cookie=Cookie("a=1;domain=test.com;path=/;HttpOnly"); +assert.ok(cookie.noscript, "HttpOnly flag parsing failed\n" + cookie.toString()); + +var test_jar = CookieJar(); +test_jar.setCookies([ + "a=1;domain=.test.com;path=/" + , "a=1;domain=.test.com;path=/" + , "a=2;domain=.test.com;path=/" + , "b=3;domain=.test.com;path=/"]); +var cookies=test_jar.getCookies(CookieAccessInfo("test.com","/")) +assert.equal(cookies.length, 2); +assert.equal(cookies[0].value, 2); + +// Test Ignore Trailing Semicolons (Github Issue #6) +var cookie = new Cookie("a=1;domain=.test.com;path=/;;;;"); +assert.equal(cookie.name, "a"); +assert.equal(cookie.value, "1"); +assert.equal(cookie.domain, ".test.com"); +assert.equal(cookie.path, "/"); +assert.deepEqual(cookie, new Cookie("a=1;domain=.test.com;path=/")); + +// Test request_path and request_domain +test_jar.setCookie(new Cookie("sub=4;path=/", "test.com")); +var cookie = test_jar.getCookie("sub", CookieAccessInfo("sub.test.com", "/")); +assert.equal(cookie, undefined); + +var cookie = test_jar.getCookie("sub", CookieAccessInfo("test.com", "/")); +assert.equal(cookie.name, "sub"); +assert.equal(cookie.domain, "test.com"); + +test_jar.setCookie(new Cookie("sub=4;path=/accounts", "test.com", "/accounts")); +var cookie = test_jar.getCookie("sub", CookieAccessInfo("test.com", "/foo")); +assert.equal(cookie, undefined); + +var cookie = test_jar.getCookie("sub", CookieAccessInfo("test.com", "/accounts")); +assert.equal(cookie.path, "/accounts"); + +test_jar.setCookie(new Cookie("sub=5;path=/", "test.com", "/accounts")); +var cookies = test_jar.getCookies(CookieAccessInfo("test.com")); +assert.equal(cookies.length, 3); diff --git a/node_modules/chai-http/node_modules/is-ip/index.js b/node_modules/chai-http/node_modules/is-ip/index.js new file mode 100644 index 0000000..c16e8b5 --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/index.js @@ -0,0 +1,14 @@ +'use strict'; +var ipRegex = require('ip-regex'); + +var ip = module.exports = function (str) { + return ipRegex({exact: true}).test(str); +}; + +ip.v4 = function (str) { + return ipRegex.v4({exact: true}).test(str); +}; + +ip.v6 = function (str) { + return ipRegex.v6({exact: true}).test(str); +}; diff --git a/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/index.js b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/index.js new file mode 100644 index 0000000..1ea8804 --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/index.js @@ -0,0 +1,20 @@ +'use strict'; + +var v4 = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(?:\\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])){3}'; +var v6 = '(?:(?:[0-9a-fA-F:]){1,4}(?:(?::(?:[0-9a-fA-F]){1,4}|:)){2,7})+'; + +var ip = module.exports = function (opts) { + opts = opts || {}; + return opts.exact ? new RegExp('(?:^' + v4 + '$)|(?:^' + v6 + '$)') : + new RegExp('(?:' + v4 + ')|(?:' + v6 + ')', 'g'); +}; + +ip.v4 = function (opts) { + opts = opts || {}; + return opts.exact ? new RegExp('^' + v4 + '$') : new RegExp(v4, 'g'); +}; + +ip.v6 = function (opts) { + opts = opts || {}; + return opts.exact ? new RegExp('^' + v6 + '$') : new RegExp(v6, 'g'); +}; diff --git a/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/license b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/license new file mode 100644 index 0000000..654d0bf --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/license @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. diff --git a/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/package.json b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/package.json new file mode 100644 index 0000000..ba6b16f --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/package.json @@ -0,0 +1,68 @@ +{ + "name": "ip-regex", + "version": "1.0.3", + "description": "Regular expression for matching IP addresses", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/sindresorhus/ip-regex" + }, + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "node test.js" + }, + "files": [ + "index.js" + ], + "keywords": [ + "text", + "regex", + "regexp", + "re", + "match", + "test", + "find", + "pattern", + "ip", + "internet", + "protocol", + "address", + "validate" + ], + "devDependencies": { + "ava": "0.0.4" + }, + "gitHead": "4237cf39da0e1b2ea883bc65bde2b69921d78ceb", + "bugs": { + "url": "https://github.com/sindresorhus/ip-regex/issues" + }, + "homepage": "https://github.com/sindresorhus/ip-regex", + "_id": "ip-regex@1.0.3", + "_shasum": "dc589076f659f419c222039a33316f1c7387effd", + "_from": "ip-regex@>=1.0.0 <2.0.0", + "_npmVersion": "2.5.0", + "_nodeVersion": "0.12.0", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "dist": { + "shasum": "dc589076f659f419c222039a33316f1c7387effd", + "tarball": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz" +} diff --git a/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/readme.md b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/readme.md new file mode 100644 index 0000000..0585f7c --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/node_modules/ip-regex/readme.md @@ -0,0 +1,59 @@ +# ip-regex [![Build Status](https://travis-ci.org/sindresorhus/ip-regex.svg?branch=master)](https://travis-ci.org/sindresorhus/ip-regex) + +> Regular expression for matching IP addresses + + +## Install + +```sh +$ npm install --save ip-regex +``` + + +## Usage + +```js +var ipRegex = require('ip-regex'); + +// contains an IP address +ipRegex().test('unicorn 192.168.0.1'); +//=> true + +// is an IP address +ipRegex({exact: true}).test('unicorn 192.168.0.1'); +//=> false + +ipRegex.v6({exact: true}).test('1:2:3:4:5:6:7:8'); +//=> true + +'unicorn 192.168.0.1 cake 1:2:3:4:5:6:7:8 rainbow'.match(ipRegex()); +//=> ['192.168.0.1', '1:2:3:4:5:6:7:8'] +``` + + +## API + +### ipRegex(options) + +Returns a regex for matching both IPv4 and IPv6. + +### ipRegex.v4(options) + +Returns a regex for matching IPv4. + +### ipRegex.v6(options) + +Returns a regex for matching IPv6. + +#### options.exact + +Type: `boolean` +Default: `false` *(Matches any IP address in a string)* + +Only match an exact string. +Useful with `RegExp#test` to check if a string is an IP address. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/chai-http/node_modules/is-ip/package.json b/node_modules/chai-http/node_modules/is-ip/package.json new file mode 100644 index 0000000..56b233c --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/package.json @@ -0,0 +1,72 @@ +{ + "name": "is-ip", + "version": "1.0.0", + "description": "Check if a string is an IP address", + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/sindresorhus/is-ip" + }, + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "node test.js" + }, + "files": [ + "index.js" + ], + "keywords": [ + "text", + "regex", + "regexp", + "re", + "match", + "test", + "find", + "pattern", + "ip", + "internet", + "protocol", + "address", + "validate", + "check", + "is", + "string" + ], + "dependencies": { + "ip-regex": "^1.0.0" + }, + "devDependencies": { + "ava": "0.0.4" + }, + "bugs": { + "url": "https://github.com/sindresorhus/is-ip/issues" + }, + "homepage": "https://github.com/sindresorhus/is-ip", + "_id": "is-ip@1.0.0", + "_shasum": "2bb6959f797ccd6f9fdc812758bcbc87c4c59074", + "_from": "is-ip@1.0.0", + "_npmVersion": "1.4.9", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + } + ], + "dist": { + "shasum": "2bb6959f797ccd6f9fdc812758bcbc87c4c59074", + "tarball": "https://registry.npmjs.org/is-ip/-/is-ip-1.0.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/is-ip/-/is-ip-1.0.0.tgz" +} diff --git a/node_modules/chai-http/node_modules/is-ip/readme.md b/node_modules/chai-http/node_modules/is-ip/readme.md new file mode 100644 index 0000000..9136313 --- /dev/null +++ b/node_modules/chai-http/node_modules/is-ip/readme.md @@ -0,0 +1,46 @@ +# is-ip [![Build Status](https://travis-ci.org/sindresorhus/is-ip.svg?branch=master)](https://travis-ci.org/sindresorhus/is-ip) + +> Check if a string is an IP address + + +## Install + +```sh +$ npm install --save is-ip +``` + + +## Usage + +```js +var isIp = require('is-ip'); + +isIp('192.168.0.1'); +//=> true + +isIp('1:2:3:4:5:6:7:8'); +//=> true + +isIp.v4('1:2:3:4:5:6:7:8'); +//=> false +``` + + +## API + +### isIp(string) + +Check if a string is IPv4 or IPv6. + +### isIp.v4(string) + +Check if a string is IPv4. + +### isIp.v6(string) + +Check if a string is IPv6. + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/chai-http/node_modules/superagent/.npmignore b/node_modules/chai-http/node_modules/superagent/.npmignore new file mode 100644 index 0000000..c44fd57 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/.npmignore @@ -0,0 +1,7 @@ +support +test +examples +*.sock +lib-cov +coverage.html +bower.json diff --git a/node_modules/chai-http/node_modules/superagent/.travis.yml b/node_modules/chai-http/node_modules/superagent/.travis.yml new file mode 100644 index 0000000..cb211cb --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/.travis.yml @@ -0,0 +1,17 @@ +sudo: false +language: node_js +node_js: + - "6.2" + - "4.4" + - "0.12" + - "0.10" + +env: + global: + - SAUCE_USERNAME='shtylman-superagent' + - SAUCE_ACCESS_KEY='39a45464-cb1d-4b8d-aa1f-83c7c04fa673' + +matrix: + include: + - node_js: "4.4" + env: BROWSER=1 diff --git a/node_modules/chai-http/node_modules/superagent/.zuul.yml b/node_modules/chai-http/node_modules/superagent/.zuul.yml new file mode 100644 index 0000000..031c56a --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/.zuul.yml @@ -0,0 +1,15 @@ +ui: mocha-bdd +server: ./test/support/server.js +browsers: + - name: chrome + version: latest + - name: firefox + version: latest + - name: safari + version: latest + - name: iphone + version: latest + - name: android + version: latest + - name: ie + version: 9..latest diff --git a/node_modules/chai-http/node_modules/superagent/Contributing.md b/node_modules/chai-http/node_modules/superagent/Contributing.md new file mode 100644 index 0000000..1eca592 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/Contributing.md @@ -0,0 +1,7 @@ +When submitting a PR, your chance of acceptance increases if you do the following: + +* Code style is consistent with existing in the file. +* Tests are passing (client and server). +* You add a test for the failing issue you are fixing. +* Code changes are focused on the area of discussion. +* Do not rebuild the distribution files or increment version numbers. diff --git a/node_modules/chai-http/node_modules/superagent/History.md b/node_modules/chai-http/node_modules/superagent/History.md new file mode 100644 index 0000000..7fa4e98 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/History.md @@ -0,0 +1,584 @@ +# 2.1.0 + + * Refactored async parsers. Now the `end` callback waits for async parsers to finish (Kornel Lesiński) + * Errors thrown in `.end()` callback don't cause the callback to be called twice (Kornel Lesiński) + * Added `headers` to `toJSON()` (Tao) + +# 2.0.0 + +## Breaking changes + +Breaking changes are in rarely used functionality, so we hope upgrade will be smooth for most users. + + * Browser: The `.parse()` method has been renamed to `.serialize()` for consistency with NodeJS version. + * Browser: Query string keys without a value used to be parsed as `'undefined'`, now their value is `''` (empty string) (shura, Kornel Lesiński). + * NodeJS: The `redirect` event is called after new query string and headers have been set and is allowed to override the request URL (Kornel Lesiński) + * `.then()` returns a real `Promise`. Note that use of superagent with promises now requires a global `Promise` object. + If you target Internet Explorer or Node 0.10, you'll need `require('es6-promise').polyfill()` or similar. + * Upgraded all dependencies (Peter Lyons) + * Renamed properties documented as `@api private` to have `_prefixed` names (Kornel Lesiński) + +## Probably not breaking changes: + + * Extracted common functions to request-base (Peter Lyons) + * Fixed race condition in pipe tests (Peter Lyons) + * Handle `FormData` error events (scriptype) + * Fixed wrong jsdoc of Request#attach (George Chung) + * Updated and improved tests (Peter Lyons) + * `request.head()` supports `.redirects(5)` call (Kornel Lesiński) + * `response` event is also emitted when using `.pipe()` + +# 1.8.2 (2016-03-20) + + * Fixed handling of HTTP status 204 with content-encoding: gzip (Andrew Shelton) + * Handling of FormData error events (scriptype) + * Fixed parsing of `vnd+json` MIME types (Kornel Lesiński) + * Aliased browser implementation of `.parse()` as `.serialize()` for forward compatibility + +# 1.8.1 (2016-03-14) + + * Fixed form-data incompatibility with IE9 + +# 1.8.0 (2016-03-09) + + * Extracted common code into request-base class (Peter Lyons) + * It does not affect the public API, but please let us know if you notice any plugins/subclasses breaking! + * Added option `{type:'auto'}` to `auth` method, which enables browser-native auth types (Jungle, Askar Yusupov) + * Added `responseType()` to set XHR `responseType` (chris) + * Switched to form-data for browserify-compatible `FormData` (Peter Lyons) + * Added `statusCode` to error response when JSON response is malformed (mattdell) + * Prevented TCP port conflicts in all tests (Peter Lyons) + * Updated form-data dependency + +# 1.7.2 (2016-01-26) + + * Fix case-sensitivity of header fields introduced by a4ddd6a. (Edward J. Jinotti) + * bump extend dependency, as former version did not contain any license information (Lukas Eipert) + +# 1.7.1 (2016-01-21) + + * Fixed a conflict with express when using npm 3.x (Glenn) + * Fixed redirects after a multipart/form-data POST request (cyclist2) + +# 1.7.0 (2016-01-18) + + * When attaching files, read default filename from the `File` object (JD Isaacks) + * Add `direction` property to `progress` events (Joseph Dykstra) + * Update component-emitter & formidable (Kornel Lesiński) + * Don't re-encode query string needlessly (Ruben Verborgh) + * ensure querystring is appended when doing `stream.pipe(request)` (Keith Grennan) + * change set header function, not call `this.request()` until call `this.end()` (vicanso) + * Add no-op `withCredentials` to Node API (markdalgleish) + * fix `delete` breaking on ie8 (kenjiokabe) + * Don't let request error override responses (Clay Reimann) + * Increased number of tests shared between node and client (Kornel Lesiński) + +# 1.6.0/1.6.1 (2015-12-09) + + * avoid misleading CORS error message + * added 'progress' event on file/form upload in Node (Olivier Lalonde) + * return raw response if the response parsing fails (Rei Colina) + * parse content-types ending with `+json` as JSON (Eiryyy) + * fix to avoid throwing errors on aborted requests (gjurgens) + * retain cookies on redirect when hosts match (Tom Conroy) + * added Bower manifest (Johnny Freeman) + * upgrade to latest cookiejar (Andy Burke) + +# 1.5.0 (2015-11-30) + + * encode array values as `key=1&key=2&key=3` etc... (aalpern, Davis Kim) + * avoid the error which is omitted from 'socket hang up' + * faster JSON parsing, handling of zlib errors (jbellenger) + * fix IE11 sends 'undefined' string if data was undefined (Vadim Goncharov) + * alias `del()` method as `delete()` (Aaron Krause) + * revert Request#parse since it was actually Response#parse + +# 1.4.0 (2015-09-14) + + * add Request#parse method to client library + * add missing statusCode in client response + * don't apply JSON heuristics if a valid parser is found + * fix detection of root object for webworkers + +# 1.3.0 (2015-08-05) + + * fix incorrect content-length of data set to buffer + * serialize request data takes into account charsets + * add basic promise support via a `then` function + +# 1.2.0 (2015-04-13) + + * add progress events to downlodas + * make usable in webworkers + * add support for 308 redirects + * update node-form-data dependency + * update to work in react native + * update node-mime dependency + +# 1.1.0 (2015-03-13) + + * Fix responseType checks without xhr2 and ie9 tests (rase-) + * errors have .status and .response fields if applicable (defunctzombie) + * fix end callback called before saving cookies (rase-) + +1.0.0 / 2015-03-08 +================== + + * All non-200 responses are treated as errors now. (The callback is called with an error when the response has a status < 200 or >= 300 now. In previous versions this would not have raised an error and the client would have to check the `res` object. See [#283](https://github.com/visionmedia/superagent/issues/283). + * keep timeouts intact across redirects (hopkinsth) + * handle falsy json values (themaarten) + * fire response events in browser version (Schoonology) + * getXHR exported in client version (KidsKilla) + * remove arity check on `.end()` callbacks (defunctzombie) + * avoid setting content-type for host objects (rexxars) + * don't index array strings in querystring (travisjeffery) + * fix pipe() with redirects (cyrilis) + * add xhr2 file download (vstirbu) + * set default response type to text/plain if not specified (warrenseine) + +0.21.0 / 2014-11-11 +================== + + * Trim text before parsing json (gjohnson) + * Update tests to express 4 (gaastonsr) + * Prevent double callback when error is thrown (pgn-vole) + * Fix missing clearTimeout (nickdima) + * Update debug (TooTallNate) + +0.20.0 / 2014-10-02 +================== + + * Add toJSON() to request and response instances. (yields) + * Prevent HEAD requests from getting parsed. (gjohnson) + * Update debug. (TooTallNate) + +0.19.1 / 2014-09-24 +================== + + * Fix basic auth issue when password is falsey value. (gjohnson) + +0.19.0 / 2014-09-24 +================== + + * Add unset() to browser. (shesek) + * Prefer XHR over ActiveX. (omeid) + * Catch parse errors. (jacwright) + * Update qs dependency. (wercker) + * Add use() to node. (Financial-Times) + * Add response text to errors. (yields) + * Don't send empty cookie headers. (undoZen) + * Don't parse empty response bodies. (DveMac) + * Use hostname when setting cookie host. (prasunsultania) + +0.18.2 / 2014-07-12 +================== + + * Handle parser errors. (kof) + * Ensure not to use default parsers when there is a user defined one. (kof) + +0.18.1 / 2014-07-05 +================== + + * Upgrade cookiejar dependency (juanpin) + * Support image mime types (nebulade) + * Make .agent chainable (kof) + * Upgrade debug (TooTallNate) + * Fix docs (aheckmann) + +0.18.0 / 2014-04-29 +=================== + +* Use "form-data" module for the multipart/form-data implementation. (TooTallNate) +* Add basic `field()` and `attach()` functions for HTML5 FormData. (TooTallNate) +* Deprecate `part()`. (TooTallNate) +* Set default user-agent header. (bevacqua) +* Add `unset()` method for removing headers. (bevacqua) +* Update cookiejar. (missinglink) +* Fix response error formatting. (shesek) + +0.17.0 / 2014-03-06 +=================== + + * supply uri malformed error to the callback (yields) + * add request event (yields) + * allow simple auth (yields) + * add request event (yields) + * switch to component/reduce (visionmedia) + * fix part content-disposition (mscdex) + * add browser testing via zuul (defunctzombie) + * adds request.use() (johntron) + +0.16.0 / 2014-01-07 +================== + + * remove support for 0.6 (superjoe30) + * fix CORS withCredentials (wejendorp) + * add "test" script (superjoe30) + * add request .accept() method (nickl-) + * add xml to mime types mappings (nickl-) + * fix parse body error on HEAD requests (gjohnson) + * fix documentation typos (matteofigus) + * fix content-type + charset (bengourley) + * fix null values on query parameters (cristiandouce) + +0.15.7 / 2013-10-19 +================== + + * pin should.js to 1.3.0 due to breaking change in 2.0.x + * fix browserify regression + +0.15.5 / 2013-10-09 +================== + + * add browser field to support browserify + * fix .field() value number support + +0.15.4 / 2013-07-09 +================== + + * node: add a Request#agent() function to set the http Agent to use + +0.15.3 / 2013-07-05 +================== + + * fix .pipe() unzipping on more recent nodes. Closes #240 + * fix passing an empty object to .query() no longer appends "?" + * fix formidable error handling + * update formidable + +0.15.2 / 2013-07-02 +================== + + * fix: emit 'end' when piping. + +0.15.1 / 2013-06-26 +================== + + * add try/catch around parseLinks + +0.15.0 / 2013-06-25 +================== + + * make `Response#toError()` have a more meaningful `message` + +0.14.9 / 2013-06-15 +================== + + * add debug()s to the node client + * add .abort() method to node client + +0.14.8 / 2013-06-13 +================== + + * set .agent = false always + * remove X-Requested-With. Closes #189 + +0.14.7 / 2013-06-06 +================== + + * fix unzip error handling + +0.14.6 / 2013-05-23 +================== + + * fix HEAD unzip bug + +0.14.5 / 2013-05-23 +================== + + * add flag to ensure the callback is __never__ invoked twice + +0.14.4 / 2013-05-22 +================== + + * add superagent.js build output + * update qs + * update emitter-component + * revert "add browser field to support browserify" see GH-221 + +0.14.3 / 2013-05-18 +================== + + * add browser field to support browserify + +0.14.2/ 2013-05-07 +================== + + * add host object check to fix serialization of File/Blobs etc as json + +0.14.1 / 2013-04-09 +================== + + * update qs + +0.14.0 / 2013-04-02 +================== + + * add client-side basic auth + * fix retaining of .set() header field case + +0.13.0 / 2013-03-13 +================== + + * add progress events to client + * add simple example + * add res.headers as alias of res.header for browser client + * add res.get(field) to node/client + +0.12.4 / 2013-02-11 +================== + + * fix get content-type even if can't get other headers in firefox. fixes #181 + +0.12.3 / 2013-02-11 +================== + + * add quick "progress" event support + +0.12.2 / 2013-02-04 +================== + + * add test to check if response acts as a readable stream + * add ReadableStream in the Response prototype. + * add test to assert correct redirection when the host changes in the location header. + * add default Accept-Encoding. Closes #155 + * fix req.pipe() return value of original stream for node parity. Closes #171 + * remove the host header when cleaning headers to properly follow the redirection. + +0.12.1 / 2013-01-10 +================== + + * add x-domain error handling + +0.12.0 / 2013-01-04 +================== + + * add header persistence on redirects + +0.11.0 / 2013-01-02 +================== + + * add .error Error object. Closes #156 + * add forcing of res.text removal for FF HEAD responses. Closes #162 + * add reduce component usage. Closes #90 + * move better-assert dep to development deps + +0.10.0 / 2012-11-14 +================== + + * add req.timeout(ms) support for the client + +0.9.10 / 2012-11-14 +================== + + * fix client-side .query(str) support + +0.9.9 / 2012-11-14 +================== + + * add .parse(fn) support + * fix socket hangup with dates in querystring. Closes #146 + * fix socket hangup "error" event when a callback of arity 2 is provided + +0.9.8 / 2012-11-03 +================== + + * add emission of error from `Request#callback()` + * add a better fix for nodes weird socket hang up error + * add PUT/POST/PATCH data support to client short-hand functions + * add .license property to component.json + * change client portion to build using component(1) + * fix GET body support [guille] + +0.9.7 / 2012-10-19 +================== + + * fix `.buffer()` `res.text` when no parser matches + +0.9.6 / 2012-10-17 +================== + + * change: use `this` when `window` is undefined + * update to new component spec [juliangruber] + * fix emission of "data" events for compressed responses without encoding. Closes #125 + +0.9.5 / 2012-10-01 +================== + + * add field name to .attach() + * add text "parser" + * refactor isObject() + * remove wtf isFunction() helper + +0.9.4 / 2012-09-20 +================== + + * fix `Buffer` responses [TooTallNate] + * fix `res.type` when a "type" param is present [TooTallNate] + +0.9.3 / 2012-09-18 +================== + + * remove __GET__ `.send()` == `.query()` special-case (__API__ change !!!) + +0.9.2 / 2012-09-17 +================== + + * add `.aborted` prop + * add `.abort()`. Closes #115 + +0.9.1 / 2012-09-07 +================== + + * add `.forbidden` response property + * add component.json + * change emitter-component to 0.0.5 + * fix client-side tests + +0.9.0 / 2012-08-28 +================== + + * add `.timeout(ms)`. Closes #17 + +0.8.2 / 2012-08-28 +================== + + * fix pathname relative redirects. Closes #112 + +0.8.1 / 2012-08-21 +================== + + * fix redirects when schema is specified + +0.8.0 / 2012-08-19 +================== + + * add `res.buffered` flag + * add buffering of text/*, json and forms only by default. Closes #61 + * add `.buffer(false)` cancellation + * add cookie jar support [hunterloftis] + * add agent functionality [hunterloftis] + +0.7.0 / 2012-08-03 +================== + + * allow `query()` to be called after the internal `req` has been created [tootallnate] + +0.6.0 / 2012-07-17 +================== + + * add `res.send('foo=bar')` default of "application/x-www-form-urlencoded" + +0.5.1 / 2012-07-16 +================== + + * add "methods" dep + * add `.end()` arity check to node callbacks + * fix unzip support due to weird node internals + +0.5.0 / 2012-06-16 +================== + + * Added "Link" response header field parsing, exposing `res.links` + +0.4.3 / 2012-06-15 +================== + + * Added 303, 305 and 307 as redirect status codes [slaskis] + * Fixed passing an object as the url + +0.4.2 / 2012-06-02 +================== + + * Added component support + * Fixed redirect data + +0.4.1 / 2012-04-13 +================== + + * Added HTTP PATCH support + * Fixed: GET / HEAD when following redirects. Closes #86 + * Fixed Content-Length detection for multibyte chars + +0.4.0 / 2012-03-04 +================== + + * Added `.head()` method [browser]. Closes #78 + * Added `make test-cov` support + * Added multipart request support. Closes #11 + * Added all methods that node supports. Closes #71 + * Added "response" event providing a Response object. Closes #28 + * Added `.query(obj)`. Closes #59 + * Added `res.type` (browser). Closes #54 + * Changed: default `res.body` and `res.files` to {} + * Fixed: port existing query-string fix (browser). Closes #57 + +0.3.0 / 2012-01-24 +================== + + * Added deflate/gzip support [guillermo] + * Added `res.type` (Content-Type void of params) + * Added `res.statusCode` to mirror node + * Added `res.headers` to mirror node + * Changed: parsers take callbacks + * Fixed optional schema support. Closes #49 + +0.2.0 / 2012-01-05 +================== + + * Added url auth support + * Added `.auth(username, password)` + * Added basic auth support [node]. Closes #41 + * Added `make test-docs` + * Added guillermo's EventEmitter. Closes #16 + * Removed `Request#data()` for SS, renamed to `send()` + * Removed `Request#data()` from client, renamed to `send()` + * Fixed array support. [browser] + * Fixed array support. Closes #35 [node] + * Fixed `EventEmitter#emit()` + +0.1.3 / 2011-10-25 +================== + + * Added error to callback + * Bumped node dep for 0.5.x + +0.1.2 / 2011-09-24 +================== + + * Added markdown documentation + * Added `request(url[, fn])` support to the client + * Added `qs` dependency to package.json + * Added options for `Request#pipe()` + * Added support for `request(url, callback)` + * Added `request(url)` as shortcut for `request.get(url)` + * Added `Request#pipe(stream)` + * Added inherit from `Stream` + * Added multipart support + * Added ssl support (node) + * Removed Content-Length field from client + * Fixed buffering, `setEncoding()` to utf8 [reported by stagas] + * Fixed "end" event when piping + +0.1.1 / 2011-08-20 +================== + + * Added `res.redirect` flag (node) + * Added redirect support (node) + * Added `Request#redirects(n)` (node) + * Added `.set(object)` header field support + * Fixed `Content-Length` support + +0.1.0 / 2011-08-09 +================== + + * Added support for multiple calls to `.data()` + * Added support for `.get(uri, obj)` + * Added GET `.data()` querystring support + * Added IE{6,7,8} support [alexyoung] + +0.0.1 / 2011-08-05 +================== + + * Initial commit + diff --git a/node_modules/chai-http/node_modules/superagent/LICENSE b/node_modules/chai-http/node_modules/superagent/LICENSE new file mode 100644 index 0000000..1b188ba --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014-2016 TJ Holowaychuk + +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. diff --git a/node_modules/chai-http/node_modules/superagent/Makefile b/node_modules/chai-http/node_modules/superagent/Makefile new file mode 100644 index 0000000..97b096c --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/Makefile @@ -0,0 +1,57 @@ + +NODETESTS ?= test/*.js test/node/*.js +BROWSERTESTS ?= test/*.js test/client/*.js +REPORTER = spec + +all: superagent.js + +test: + @if [ "x$(BROWSER)" = "x" ]; then make test-node; else make test-browser; fi + +test-node: + @NODE_ENV=test NODE_TLS_REJECT_UNAUTHORIZED=0 ./node_modules/.bin/mocha \ + --require should \ + --reporter $(REPORTER) \ + --timeout 5000 \ + --growl \ + $(NODETESTS) + +test-cov: lib-cov + SUPERAGENT_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html + +test-browser: + ./node_modules/.bin/zuul -- $(BROWSERTESTS) + +test-browser-local: + ./node_modules/.bin/zuul --local 4000 -- $(BROWSERTESTS) + +lib-cov: + jscoverage lib lib-cov + +superagent.js: lib/node/*.js lib/node/parsers/*.js + @./node_modules/.bin/browserify \ + --standalone superagent \ + --outfile superagent.js . + +test-server: + @node test/server + +docs: index.html test-docs docs/index.md + +index.html: docs/index.md docs/head.html docs/tail.html + marked < $< \ + | cat docs/head.html - docs/tail.html \ + > $@ + +docclean: + rm -f index.html test.html + +test-docs: docs/head.html docs/tail.html + make test REPORTER=doc \ + | cat docs/head.html - docs/tail.html \ + > test.html + +clean: + rm -fr superagent.js components + +.PHONY: test-cov test docs test-docs clean test-browser-local diff --git a/node_modules/chai-http/node_modules/superagent/Readme.md b/node_modules/chai-http/node_modules/superagent/Readme.md new file mode 100644 index 0000000..de2d851 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/Readme.md @@ -0,0 +1,130 @@ +# SuperAgent + +SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.io/superagent/). + +![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png) + +## Installation + +node: + +``` +$ npm install superagent +``` + +component: + +``` +$ component install visionmedia/superagent +``` + +Works with [browserify](https://github.com/substack/node-browserify) and should work with [webpack](https://github.com/visionmedia/superagent/wiki/Superagent-for-Webpack) + +```js +request + .post('/api/pet') + .send({ name: 'Manny', species: 'cat' }) + .set('X-API-Key', 'foobar') + .set('Accept', 'application/json') + .end(function(err, res){ + // Calling the end function will send the request + }); +``` + +## Supported browsers + +Tested browsers: + +- Latest Android +- Latest Firefox +- Latest Chrome +- IE10 through latest. IE9 with polyfills. +- Latest iPhone +- Latest Safari + +Even though IE9 is supported, a polyfill for `window.FormData` is required for `.field()`, and `window.btoa` is needed to use basic auth. + +# Plugins + +Superagent is easily extended via plugins. + +```js +var nocache = require('superagent-no-cache'); +var request = require('superagent'); +var prefix = require('superagent-prefix')('/static'); + +request +.get('/some-url') +.use(prefix) // Prefixes *only* this request +.use(nocache) // Prevents caching of *only* this request +.end(function(err, res){ + // Do something +}); +``` + +Existing plugins: + * [superagent-no-cache](https://github.com/johntron/superagent-no-cache) - prevents caching by including Cache-Control header + * [superagent-prefix](https://github.com/johntron/superagent-prefix) - prefixes absolute URLs (useful in test environment) + * [superagent-suffix](https://github.com/timneutkens1/superagent-suffix) - suffix URLs with a given path + * [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL + * [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API + * [superagent-cache](https://github.com/jpodwys/superagent-cache) - superagent with built-in, flexible caching + * [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent + * [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases + * [superagent-promise-plugin](https://github.com/jomaxx/superagent-promise-plugin) - Shims req.end to return a promise when executed with no callback. + * [superagent-use](https://github.com/koenpunt/superagent-use) - A client addon to apply plugins to all requests. + * [superagent-httpbackend](https://www.npmjs.com/package/superagent-httpbackend) - stub out requests using AngularJS' $httpBackend syntax + * [superagent-throttle](https://github.com/leviwheatcroft/superagent-throttle) - queues and intelligently throttles requests + * [superagent-charset](https://github.com/magicdawn/superagent-charset) - add charset support for node's superagent + +Please prefix your plugin with `superagent-*` so that it can easily be found by others. + +For superagent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki). + +## Running node tests + +Install dependencies: + +```shell +$ npm install +``` +Run em! + +```shell +$ make test +``` + +## Running browser tests + +Install dependencies: + +```shell +$ npm install +``` + +Start the test runner: + +```shell +$ make test-browser-local +``` + +Visit `http://localhost:4000/__zuul` in your browser. + +Edit tests and refresh your browser. You do not have to restart the test runner. + + +## Packaging Notes for Developers + +**npm (for node)** is configured via the `package.json` file and the `.npmignore` file. Key metadata in the `package.json` file is the `version` field which should be changed according to semantic versioning and have a 1-1 correspondence with git tags. So for example, if you were to `git show v1.5.0:package.json | grep version`, you should see `"version": "1.5.0",` and this should hold true for every release. This can be handled via the `npm version` command. Be aware that when publishing, npm will presume the version being published should also be tagged in npm as `latest`, which is OK for normal incremental releases. For betas and minor/patch releases to older versions, be sure to include `--tag` appropriately to avoid an older release getting tagged as `latest`. + +**npm (for browser standalone)** When we publish versions to npm, we run `make superagent.js` which generates the standalone `superagent.js` file via `browserify`, and this file is included in the package published to npm (but this file is never checked into the git repository). If users want to install via npm but serve a single `.js` file directly to the browser, the `node_modules/superagent/superagent.js` is a standalone browserified file ready to go for that purpose. It is not minified. + +**npm (for browserify)** is handled via the `package.json` `browser` field which allows users to install superagent via npm, reference it from their browser code with `require('superagent')`, and then build their own application bundle via `browserify`, which will use `lib/client.js` as the superagent entrypoint. + +**bower** is configured via the `bower.json` file. Bower installs files directly from git/github without any transformation. + +**component** is configured via the `component.json` file. + +## License + +MIT diff --git a/node_modules/chai-http/node_modules/superagent/component.json b/node_modules/chai-http/node_modules/superagent/component.json new file mode 100644 index 0000000..3e62a06 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/component.json @@ -0,0 +1,20 @@ +{ + "name": "superagent", + "repo": "visionmedia/superagent", + "version": "2.1.0", + "description": "elegant & feature rich browser / node HTTP with a fluent API", + "keywords": [ + "http", + "ajax", + "request", + "agent" + ], + "scripts": [ + "lib/client.js" + ], + "main": "lib/client.js", + "dependencies": { + "component/emitter": "*" + }, + "license": "MIT" +} diff --git a/node_modules/chai-http/node_modules/superagent/docs/head.html b/node_modules/chai-http/node_modules/superagent/docs/head.html new file mode 100644 index 0000000..b4479e9 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/docs/head.html @@ -0,0 +1,10 @@ + + + + + SuperAgent — elegant API for AJAX in Node and browsers + + + + +
diff --git a/node_modules/chai-http/node_modules/superagent/docs/images/bg.png b/node_modules/chai-http/node_modules/superagent/docs/images/bg.png new file mode 100644 index 0000000..ca3d267 Binary files /dev/null and b/node_modules/chai-http/node_modules/superagent/docs/images/bg.png differ diff --git a/node_modules/chai-http/node_modules/superagent/docs/index.md b/node_modules/chai-http/node_modules/superagent/docs/index.md new file mode 100644 index 0000000..351afe8 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/docs/index.md @@ -0,0 +1,476 @@ + +# SuperAgent + + Super Agent is light-weight progressive ajax API crafted for flexibility, readability, and a low learning curve after being frustrated with many of the existing request APIs. It also works with Node.js! + + request + .post('/api/pet') + .send({ name: 'Manny', species: 'cat' }) + .set('X-API-Key', 'foobar') + .set('Accept', 'application/json') + .end(function(err, res){ + if (err || !res.ok) { + alert('Oh no! error'); + } else { + alert('yay got ' + JSON.stringify(res.body)); + } + }); + +## Test documentation + + The following [test documentation](docs/test.html) was generated with [Mocha's](http://mochajs.org/) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation. + +## Request basics + + A request can be initiated by invoking the appropriate method on the `request` object, then calling `.end()` to send the request. For example a simple GET request: + + request + .get('/search') + .end(function(err, res){ + + }); + + A method string may also be passed: + + request('GET', '/search').end(callback); + +ES6 promises are supported. Instead of `.end()` you can call `.then()`: + + request('GET', '/search').then(success, failure); + + The __node__ client may also provide absolute urls: + + request + .get('http://example.com/search') + .end(function(err, res){ + + }); + + __DELETE__, __HEAD__, __POST__, __PUT__ and other __HTTP__ verbs may also be used, simply change the method name: + + request + .head('/favicon.ico') + .end(function(err, res){ + + }); + + __DELETE__ is a special-case, as it's a reserved word, so the method is named `.del()`: + + request + .del('/user/1') + .end(function(err, res){ + + }); + + The HTTP method defaults to __GET__, so if you wish, the following is valid: + + request('/search', function(err, res){ + + }); + +## Setting header fields + + Setting header fields is simple, invoke `.set()` with a field name and value: + + request + .get('/search') + .set('API-Key', 'foobar') + .set('Accept', 'application/json') + .end(callback); + + You may also pass an object to set several fields in a single call: + + request + .get('/search') + .set({ 'API-Key': 'foobar', Accept: 'application/json' }) + .end(callback); + +## GET requests + + The `.query()` method accepts objects, which when used with the __GET__ method will form a query-string. The following will produce the path `/search?query=Manny&range=1..5&order=desc`. + + request + .get('/search') + .query({ query: 'Manny' }) + .query({ range: '1..5' }) + .query({ order: 'desc' }) + .end(function(err, res){ + + }); + + Or as a single object: + + request + .get('/search') + .query({ query: 'Manny', range: '1..5', order: 'desc' }) + .end(function(err, res){ + + }); + + The `.query()` method accepts strings as well: + + request + .get('/querystring') + .query('search=Manny&range=1..5') + .end(function(err, res){ + + }); + + Or joined: + + request + .get('/querystring') + .query('search=Manny') + .query('range=1..5') + .end(function(err, res){ + + }); + +## HEAD requests + +You can also use the `.query()` method for HEAD requests. The following will produce the path `/users?email=joe@smith.com`. + + request + .head('/users') + .query({ email: 'joe@smith.com' }) + .end(function(err, res){ + + }); + +## POST / PUT requests + + A typical JSON __POST__ request might look a little like the following, where we set the Content-Type header field appropriately, and "write" some data, in this case just a JSON string. + + request.post('/user') + .set('Content-Type', 'application/json') + .send('{"name":"tj","pet":"tobi"}') + .end(callback) + + Since JSON is undoubtably the most common, it's the _default_! The following example is equivalent to the previous. + + request.post('/user') + .send({ name: 'tj', pet: 'tobi' }) + .end(callback) + + Or using multiple `.send()` calls: + + request.post('/user') + .send({ name: 'tj' }) + .send({ pet: 'tobi' }) + .end(callback) + + By default sending strings will set the Content-Type to `application/x-www-form-urlencoded`, + multiple calls will be concatenated with `&`, here resulting in `name=tj&pet=tobi`: + + request.post('/user') + .send('name=tj') + .send('pet=tobi') + .end(callback); + + SuperAgent formats are extensible, however by default "json" and "form" are supported. To send the data as `application/x-www-form-urlencoded` simply invoke `.type()` with "form", where the default is "json". This request will POST the body "name=tj&pet=tobi". + + request.post('/user') + .type('form') + .send({ name: 'tj' }) + .send({ pet: 'tobi' }) + .end(callback) + + Note: "form" is aliased as "form-data" and "urlencoded" for backwards compat. + +## Setting the Content-Type + + The obvious solution is to use the `.set()` method: + + request.post('/user') + .set('Content-Type', 'application/json') + + As a short-hand the `.type()` method is also available, accepting + the canonicalized MIME type name complete with type/subtype, or + simply the extension name such as "xml", "json", "png", etc: + + request.post('/user') + .type('application/json') + + request.post('/user') + .type('json') + + request.post('/user') + .type('png') + +## Serializing request body + +Superagent will automatically serialize JSON and forms. If you want to send the payload in a custom format, you can replace the built-in serialization with `.serialize()` method. + +## Setting Accept + +In a similar fashion to the `.type()` method it is also possible to set the Accept header via the short hand method `.accept()`. Which references `request.types` as well allowing you to specify either the full canonicalized MIME type name as type/subtype, or the extension suffix form as "xml", "json", "png", etc for convenience: + + request.get('/user') + .accept('application/json') + + request.get('/user') + .accept('json') + + request.post('/user') + .accept('png') + +## Query strings + + `res.query(obj)` is a method which may be used to build up a query-string. For example populating `?format=json&dest=/login` on a __POST__: + + request + .post('/') + .query({ format: 'json' }) + .query({ dest: '/login' }) + .send({ post: 'data', here: 'wahoo' }) + .end(callback); + +## Parsing response bodies + + Super Agent will parse known response-body data for you, currently supporting `application/x-www-form-urlencoded`, `application/json`, and `multipart/form-data`. + + You can set a custom parser (that takes precedence over built-in parsers) with the `.buffer(true).parse(fn)` method. If response buffering is not enabled (`.buffer(false)`) then the `response` event will be emitted without waiting for the body parser to finish, so `response.body` won't be available. + +### JSON / Urlencoded + + The property `res.body` is the parsed object, for example if a request responded with the JSON string '{"user":{"name":"tobi"}}', `res.body.user.name` would be "tobi". Likewise the x-www-form-urlencoded value of "user[name]=tobi" would yield the same result. + +### Multipart + + The Node client supports _multipart/form-data_ via the [Formidable](https://github.com/felixge/node-formidable) module. When parsing multipart responses, the object `res.files` is also available to you. Suppose for example a request responds with the following multipart body: + + --whoop + Content-Disposition: attachment; name="image"; filename="tobi.png" + Content-Type: image/png + + ... data here ... + --whoop + Content-Disposition: form-data; name="name" + Content-Type: text/plain + + Tobi + --whoop-- + + You would have the values `res.body.name` provided as "Tobi", and `res.files.image` as a `File` object containing the path on disk, filename, and other properties. + +## Response properties + + Many helpful flags and properties are set on the `Response` object, ranging from the response text, parsed response body, header fields, status flags and more. + +### Response text + + The `res.text` property contains the unparsed response body string. This + property is always present for the client API, and only when the mime type + matches "text/*", "*/json", or "x-www-form-urlencoded" by default for node. The + reasoning is to conserve memory, as buffering text of large bodies such as multipart files or images is extremely inefficient. + + To force buffering see the "Buffering responses" section. + +### Response body + + Much like SuperAgent can auto-serialize request data, it can also automatically parse it. When a parser is defined for the Content-Type, it is parsed, which by default includes "application/json" and "application/x-www-form-urlencoded". The parsed object is then available via `res.body`. + +### Response header fields + + The `res.header` contains an object of parsed header fields, lowercasing field names much like node does. For example `res.header['content-length']`. + +### Response Content-Type + + The Content-Type response header is special-cased, providing `res.type`, which is void of the charset (if any). For example the Content-Type of "text/html; charset=utf8" will provide "text/html" as `res.type`, and the `res.charset` property would then contain "utf8". + +### Response status + + The response status flags help determine if the request was a success, among other useful information, making SuperAgent ideal for interacting with RESTful web services. These flags are currently defined as: + + var type = status / 100 | 0; + + // status / class + res.status = status; + res.statusType = type; + + // basics + res.info = 1 == type; + res.ok = 2 == type; + res.clientError = 4 == type; + res.serverError = 5 == type; + res.error = 4 == type || 5 == type; + + // sugar + res.accepted = 202 == status; + res.noContent = 204 == status || 1223 == status; + res.badRequest = 400 == status; + res.unauthorized = 401 == status; + res.notAcceptable = 406 == status; + res.notFound = 404 == status; + res.forbidden = 403 == status; + +## Aborting requests + + To abort requests simply invoke the `req.abort()` method. + +## Request timeouts + + A timeout can be applied by invoking `req.timeout(ms)`, after which an error + will be triggered. To differentiate between other errors the `err.timeout` property + is set to the `ms` value. __NOTE__ that this is a timeout applied to the request + and all subsequent redirects, not per request. + +## Authentication + + In both Node and browsers auth available via the `.auth()` method: + + request + .get('http://local') + .auth('tobi', 'learnboost') + .end(callback); + + + In the _Node_ client Basic auth can be in the URL as "user:pass": + + request.get('http://tobi:learnboost@local').end(callback); + + By default only `Basic` auth is used. In browser you can add `{type:'auto'}` to enable all methods built-in in the browser (Digest, NTLM, etc.): + + request.auth('digest', 'secret', {type:'auto'}) + +## Following redirects + + By default up to 5 redirects will be followed, however you may specify this with the `res.redirects(n)` method: + + request + .get('/some.png') + .redirects(2) + .end(callback); + +## Piping data + + The Node client allows you to pipe data to and from the request. For example piping a file's contents as the request: + + var request = require('superagent') + , fs = require('fs'); + + var stream = fs.createReadStream('path/to/my.json'); + var req = request.post('/somewhere'); + req.type('json'); + stream.pipe(req); + + Or piping the response to a file: + + var request = require('superagent') + , fs = require('fs'); + + var stream = fs.createWriteStream('path/to/my.json'); + var req = request.get('/some.json'); + req.pipe(stream); + +## Multipart requests + + Super Agent is also great for _building_ multipart requests for which it provides methods `.attach()` and `.field()`. + +### Attaching files + + As mentioned a higher-level API is also provided, in the form of `.attach(name, [path], [filename])` and `.field(name, value)`. Attaching several files is simple, you can also provide a custom filename for the attachment, otherwise the basename of the attached file is used. + + request + .post('/upload') + .attach('avatar', 'path/to/tobi.png', 'user.png') + .attach('image', 'path/to/loki.png') + .attach('file', 'path/to/jane.png') + .end(callback); + +### Field values + + Much like form fields in HTML, you can set field values with the `.field(name, value)` method. Suppose you want to upload a few images with your name and email, your request might look something like this: + + request + .post('/upload') + .field('user[name]', 'Tobi') + .field('user[email]', 'tobi@learnboost.com') + .attach('image', 'path/to/tobi.png') + .end(callback); + +## Compression + + The node client supports compressed responses, best of all, you don't have to do anything! It just works. + +## Buffering responses + + To force buffering of response bodies as `res.text` you may invoke `req.buffer()`. To undo the default of buffering for text responses such + as "text/plain", "text/html" etc you may invoke `req.buffer(false)`. + + When buffered the `res.buffered` flag is provided, you may use this to + handle both buffered and unbuffered responses in the same callback. + +## CORS + + The `.withCredentials()` method enables the ability to send cookies + from the origin, however only when "Access-Control-Allow-Origin" is + _not_ a wildcard ("*"), and "Access-Control-Allow-Credentials" is "true". + + request + .get('http://localhost:4001/') + .withCredentials() + .end(function(err, res){ + assert(200 == res.status); + assert('tobi' == res.text); + next(); + }) + +## Error handling + +Your callback function will always be passed two arguments: error and response. If no error occurred, the first argument will be null: + + request + .post('/upload') + .attach('image', 'path/to/tobi.png') + .end(function(err, res){ + + }); + + An "error" event is also emitted, with you can listen for: + + request + .post('/upload') + .attach('image', 'path/to/tobi.png') + .on('error', handle) + .end(function(err, res){ + + }); + + Note that a 4xx or 5xx response with super agent **are** considered an error by default. For example if you get a 500 or 403 response, this status information will be available via `err.status`. Errors from such responses also contain an `err.response` field with all of the properties mentioned in "Response properties". The library behaves in this way to handle the common case of wanting success responses and treating HTTP error status codes as errors while still allowing for custom logic around specific error conditions. + + Network failures, timeouts, and other errors that produce no response will contain no `err.status` or `err.response` fields. + + If you wish to handle 404 or other HTTP error responses, you can query the `err.status` property. + When an HTTP error occurs (4xx or 5xx response) the `res.error` property is an `Error` object, + this allows you to perform checks such as: + + if (err && err.status === 404) { + alert('oh no ' + res.body.message); + } + else if (err) { + // all other error types we handle generically + } + +## Promise and Generator support + +Superagent's request is a "thenable" object that's compatible with JavaScript promises and `async`/`await` syntax. + +Libraries like [co](https://github.com/tj/co) or a web framework like [koa](https://github.com/koajs/koa) can `yield` on any superagent method: + + var res = yield request + .get('http://local') + .auth('tobi', 'learnboost') + +Note that superagent expects the global `Promise` object to be present. You'll need a polyfill to use promises in Internet Explorer or Node.js 0.10. + + +## Browser and node versions + +Superagent has two implementations: one for web browsers (using XHR) and one for Node.JS (using core http module). By default Browserify and WebPack will pick the browser version. + +If want to use WebPack to compile code for Node.JS, you *must* specify [node target](webpack.github.io/docs/configuration.html#target) in its configuration. + +### Using browser version in electron + +[Electron](http://electron.atom.io/) developers report if you would prefer to use the browser version of superagent instead of the Node version, you can `require('superagent/superagent')`. Your requests will now show up in the Chrome developer tools Network tab. Note this environment is not covered by automated test suite and not officially supported. diff --git a/node_modules/chai-http/node_modules/superagent/docs/style.css b/node_modules/chai-http/node_modules/superagent/docs/style.css new file mode 100644 index 0000000..9ca0e5c --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/docs/style.css @@ -0,0 +1,81 @@ +body { + padding: 40px 80px; + font: 14px/1.5 "Helvetica Neue", Helvetica, sans-serif; + background: #181818 url(images/bg.png); + text-align: center; +} + +#content { + margin: 0 auto; + padding: 10px 40px; + text-align: left; + background: white; + width: 50%; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + -webkit-box-shadow: 0 2px 5px 0 black; +} + +#menu { + font-size: 13px; + margin: 0; + padding: 0; + text-align: left; + position: fixed; + top: 15px; + left: 15px; +} + +#menu ul { + margin: 0; + padding: 0; +} + +#menu li { + list-style: none; +} + +#menu a { + color: rgba(255,255,255,.5); + text-decoration: none; +} + +#menu a:hover { + color: white; +} + +#menu .active a { + color: white; +} + +pre { + padding: 10px; +} + +code { + font: 12px/1 monaco, monospace; +} + +p code { + border: 1px solid #ECEA75; + padding: 1px 3px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + background: #FDFCD1; +} + +pre { + padding: 20px 25px; + border: 1px solid #ddd; + -webkit-box-shadow: inset 0 0 5px #eee; + -moz-box-shadow: inset 0 0 5px #eee; + box-shadow: inset 0 0 5px #eee; +} + +code .comment { color: #ddd } +code .init { color: #2F6FAD } +code .string { color: #5890AD } +code .keyword { color: #8A6343 } +code .number { color: #2F6FAD } \ No newline at end of file diff --git a/node_modules/chai-http/node_modules/superagent/docs/tail.html b/node_modules/chai-http/node_modules/superagent/docs/tail.html new file mode 100644 index 0000000..579fb59 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/docs/tail.html @@ -0,0 +1,29 @@ +
+ Fork me on GitHub + + + + + + + diff --git a/node_modules/chai-http/node_modules/superagent/docs/test.html b/node_modules/chai-http/node_modules/superagent/docs/test.html new file mode 100644 index 0000000..199241f --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/docs/test.html @@ -0,0 +1,2082 @@ + + + + SuperAgent - Ajax with less suck + + + + + + + + + +
+

request

+
+
+

with a callback

+
+
should invoke .end()
+
request
+.get(uri + '/login', function(err, res){
+  assert(res.status == 200);
+  done();
+})
+
+
+
+

.end()

+
+
should issue a request
+
request
+.get(uri + '/login')
+.end(function(err, res){
+  assert(res.status == 200);
+  done();
+});
+
+
+
+

res.error

+
+
should should be an Error object
+
request
+.get(uri + '/error')
+.end(function(err, res){
+  if (NODE) {
+    res.error.message.should.equal('cannot GET /error (500)');
+  }
+  else {
+    res.error.message.should.equal('cannot GET ' + uri + '/error (500)');
+  }
+  assert(res.error.status === 500);
+  assert(err, 'should have an error for 500');
+  assert.equal(err.message, 'Internal Server Error');
+  done();
+});
+
+
+
+

res.header

+
+
should be an object
+
request
+.get(uri + '/login')
+.end(function(err, res){
+  assert('Express' == res.header['x-powered-by']);
+  done();
+});
+
+
+
+

res.charset

+
+
should be set when present
+
request
+.get(uri + '/login')
+.end(function(err, res){
+  res.charset.should.equal('utf-8');
+  done();
+});
+
+
+
+

res.statusType

+
+
should provide the first digit
+
request
+.get(uri + '/login')
+.end(function(err, res){
+  assert(!err, 'should not have an error for success responses');
+  assert(200 == res.status);
+  assert(2 == res.statusType);
+  done();
+});
+
+
+
+

res.type

+
+
should provide the mime-type void of params
+
request
+.get(uri + '/login')
+.end(function(err, res){
+  res.type.should.equal('text/html');
+  res.charset.should.equal('utf-8');
+  done();
+});
+
+
+
+

req.set(field, val)

+
+
should set the header field
+
request
+.post(uri + '/echo')
+.set('X-Foo', 'bar')
+.set('X-Bar', 'baz')
+.end(function(err, res){
+  assert('bar' == res.header['x-foo']);
+  assert('baz' == res.header['x-bar']);
+  done();
+})
+
+
+
+

req.set(obj)

+
+
should set the header fields
+
request
+.post(uri + '/echo')
+.set({ 'X-Foo': 'bar', 'X-Bar': 'baz' })
+.end(function(err, res){
+  assert('bar' == res.header['x-foo']);
+  assert('baz' == res.header['x-bar']);
+  done();
+})
+
+
+
+

req.type(str)

+
+
should set the Content-Type
+
request
+.post(uri + '/echo')
+.type('text/x-foo')
+.end(function(err, res){
+  res.header['content-type'].should.equal('text/x-foo');
+  done();
+});
+
should map "json"
+
request
+.post(uri + '/echo')
+.type('json')
+.send('{"a": 1}')
+.end(function(err, res){
+  res.should.be.json;
+  done();
+});
+
should map "html"
+
request
+.post(uri + '/echo')
+.type('html')
+.end(function(err, res){
+  res.header['content-type'].should.equal('text/html');
+  done();
+});
+
+
+
+

req.accept(str)

+
+
should set Accept
+
request
+.get(uri + '/echo')
+.accept('text/x-foo')
+.end(function(err, res){
+   res.header['accept'].should.equal('text/x-foo');
+   done();
+});
+
should map "json"
+
request
+.get(uri + '/echo')
+.accept('json')
+.end(function(err, res){
+  res.header['accept'].should.equal('application/json');
+  done();
+});
+
should map "xml"
+
request
+.get(uri + '/echo')
+.accept('xml')
+.end(function(err, res){
+  res.header['accept'].should.equal('application/xml');
+  done();
+});
+
should map "html"
+
request
+.get(uri + '/echo')
+.accept('html')
+.end(function(err, res){
+  res.header['accept'].should.equal('text/html');
+  done();
+});
+
+
+
+

req.send(str)

+
+
should write the string
+
request
+.post(uri + '/echo')
+.type('json')
+.send('{"name":"tobi"}')
+.end(function(err, res){
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+});
+
+
+
+

req.send(Object)

+
+
should default to json
+
request
+.post(uri + '/echo')
+.send({ name: 'tobi' })
+.end(function(err, res){
+  res.should.be.json
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+});
+
+

when called several times

+
+
should merge the objects
+
request
+.post(uri + '/echo')
+.send({ name: 'tobi' })
+.send({ age: 1 })
+.end(function(err, res){
+  res.should.be.json
+  if (NODE) {
+    res.buffered.should.be.true;
+  }
+  res.text.should.equal('{"name":"tobi","age":1}');
+  done();
+});
+
+
+
+
+
+

.end(fn)

+
+
should check arity
+
request
+.post(uri + '/echo')
+.send({ name: 'tobi' })
+.end(function(err, res){
+  assert(null == err);
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+});
+
should emit request
+
var req = request.post(uri + '/echo');
+req.on('request', function(request){
+  assert(req == request);
+  done();
+});
+req.end();
+
should emit response
+
request
+.post(uri + '/echo')
+.send({ name: 'tobi' })
+.on('response', function(res){
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+})
+.end();
+
+
+
+

.then(fulfill, reject)

+
+
should support successful fulfills with .then(fulfill)
+
request
+.post(uri + '/echo')
+.send({ name: 'tobi' })
+.then(function(res) {
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+})
+
should reject an error with .then(null, reject)
+
request
+.get(uri + '/error')
+.then(null, function(err) {
+  assert(err.status == 500);
+  assert(err.response.text == 'boom');
+  done();
+})
+
+
+
+

.abort()

+
+
should abort the request
+
var req = request
+.get(uri + '/delay/3000')
+.end(function(err, res){
+  assert(false, 'should not complete the request');
+});
+req.on('abort', done);
+setTimeout(function() {
+  req.abort();
+}, 1000);
+
+
+
+
+
+

request

+
+
+

persistent agent

+
+
should gain a session on POST
+
agent3
+  .post('http://localhost:4000/signin')
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    should.not.exist(res.headers['set-cookie']);
+    res.text.should.containEql('dashboard');
+    done();
+  });
+
should start with empty session (set cookies)
+
agent1
+  .get('http://localhost:4000/dashboard')
+  .end(function(err, res) {
+    should.exist(err);
+    res.should.have.status(401);
+    should.exist(res.headers['set-cookie']);
+    done();
+  });
+
should gain a session (cookies already set)
+
agent1
+  .post('http://localhost:4000/signin')
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    should.not.exist(res.headers['set-cookie']);
+    res.text.should.containEql('dashboard');
+    done();
+  });
+
should persist cookies across requests
+
agent1
+  .get('http://localhost:4000/dashboard')
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    done();
+  });
+
should have the cookie set in the end callback
+
agent4
+  .post('http://localhost:4000/setcookie')
+  .end(function(err, res) {
+    agent4
+      .get('http://localhost:4000/getcookie')
+      .end(function(err, res) {
+        should.not.exist(err);
+        res.should.have.status(200);
+        assert(res.text === 'jar');
+        done();
+      });
+  });
+
should not share cookies
+
agent2
+  .get('http://localhost:4000/dashboard')
+  .end(function(err, res) {
+    should.exist(err);
+    res.should.have.status(401);
+    done();
+  });
+
should not lose cookies between agents
+
agent1
+  .get('http://localhost:4000/dashboard')
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    done();
+  });
+
should be able to follow redirects
+
agent1
+  .get('http://localhost:4000/')
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    res.text.should.containEql('dashboard');
+    done();
+  });
+
should be able to post redirects
+
agent1
+  .post('http://localhost:4000/redirect')
+  .send({ foo: 'bar', baz: 'blaaah' })
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    res.text.should.containEql('simple');
+    res.redirects.should.eql(['http://localhost:4000/simple']);
+    done();
+  });
+
should be able to limit redirects
+
agent1
+  .get('http://localhost:4000/')
+  .redirects(0)
+  .end(function(err, res) {
+    should.exist(err);
+    res.should.have.status(302);
+    res.redirects.should.eql([]);
+    res.header.location.should.equal('/dashboard');
+    done();
+  });
+
should be able to create a new session (clear cookie)
+
agent1
+  .post('http://localhost:4000/signout')
+  .end(function(err, res) {
+    should.not.exist(err);
+    res.should.have.status(200);
+    should.exist(res.headers['set-cookie']);
+    done();
+  });
+
should regenerate with an empty session
+
agent1
+  .get('http://localhost:4000/dashboard')
+  .end(function(err, res) {
+    should.exist(err);
+    res.should.have.status(401);
+    should.not.exist(res.headers['set-cookie']);
+    done();
+  });
+
+
+
+
+
+

Basic auth

+
+
+

when credentials are present in url

+
+
should set Authorization
+
request
+.get('http://tobi:learnboost@localhost:3010')
+.end(function(err, res){
+  res.status.should.equal(200);
+  done();
+});
+
+
+
+

req.auth(user, pass)

+
+
should set Authorization
+
request
+.get('http://localhost:3010')
+.auth('tobi', 'learnboost')
+.end(function(err, res){
+  res.status.should.equal(200);
+  done();
+});
+
+
+
+

req.auth(user + ":" + pass)

+
+
should set authorization
+
request
+.get('http://localhost:3010/again')
+.auth('tobi')
+.end(function(err, res){
+  res.status.should.eql(200);
+  done();
+});
+
+
+
+
+
+

[node] request

+
+
+

res.statusCode

+
+
should set statusCode
+
request
+.get('http://localhost:5000/login', function(err, res){
+  assert(res.statusCode === 200);
+  done();
+})
+
+
+
+

with an object

+
+
should format the url
+
request
+.get(url.parse('http://localhost:5000/login'))
+.end(function(err, res){
+  assert(res.ok);
+  done();
+})
+
+
+
+

without a schema

+
+
should default to http
+
request
+.get('localhost:5000/login')
+.end(function(err, res){
+  assert(res.status == 200);
+  done();
+})
+
+
+
+

req.toJSON()

+
+
should describe the request
+
request
+.post(':5000/echo')
+.send({ foo: 'baz' })
+.end(function(err, res){
+  var obj = res.request.toJSON();
+  assert('POST' == obj.method);
+  assert(':5000/echo' == obj.url);
+  assert('baz' == obj.data.foo);
+  done();
+});
+
+
+
+

should allow the send shorthand

+
+
with callback in the method call
+
request
+.get('http://localhost:5000/login', function(err, res) {
+    assert(res.status == 200);
+    done();
+});
+
with data in the method call
+
request
+.post('http://localhost:5000/echo', { foo: 'bar' })
+.end(function(err, res) {
+  assert('{"foo":"bar"}' == res.text);
+  done();
+});
+
with callback and data in the method call
+
request
+.post('http://localhost:5000/echo', { foo: 'bar' }, function(err, res) {
+  assert('{"foo":"bar"}' == res.text);
+  done();
+});
+
+
+
+

res.toJSON()

+
+
should describe the response
+
request
+.post('http://localhost:5000/echo')
+.send({ foo: 'baz' })
+.end(function(err, res){
+  var obj = res.toJSON();
+  assert('object' == typeof obj.header);
+  assert('object' == typeof obj.req);
+  assert(200 == obj.status);
+  assert('{"foo":"baz"}' == obj.text);
+  done();
+});
+
+
+
+

res.links

+
+
should default to an empty object
+
request
+.get('http://localhost:5000/login')
+.end(function(err, res){
+  res.links.should.eql({});
+  done();
+})
+
should parse the Link header field
+
request
+.get('http://localhost:5000/links')
+.end(function(err, res){
+  res.links.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2');
+  done();
+})
+
+
+
+

req.unset(field)

+
+
should remove the header field
+
request
+.post('http://localhost:5000/echo')
+.unset('User-Agent')
+.end(function(err, res){
+  assert(void 0 == res.header['user-agent']);
+  done();
+})
+
+
+
+

req.write(str)

+
+
should write the given data
+
var req = request.post('http://localhost:5000/echo');
+req.set('Content-Type', 'application/json');
+req.write('{"name"').should.be.a.boolean;
+req.write(':"tobi"}').should.be.a.boolean;
+req.end(function(err, res){
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+});
+
+
+
+

req.pipe(stream)

+
+
should pipe the response to the given stream
+
var stream = new EventEmitter;
+stream.buf = '';
+stream.writable = true;
+stream.write = function(chunk){
+  this.buf += chunk;
+};
+stream.end = function(){
+  this.buf.should.equal('{"name":"tobi"}');
+  done();
+};
+request
+.post('http://localhost:5000/echo')
+.send('{"name":"tobi"}')
+.pipe(stream);
+
+
+
+

.buffer()

+
+
should enable buffering
+
request
+.get('http://localhost:5000/custom')
+.buffer()
+.end(function(err, res){
+  assert(null == err);
+  assert('custom stuff' == res.text);
+  assert(res.buffered);
+  done();
+});
+
+
+
+

.buffer(false)

+
+
should disable buffering
+
request
+.post('http://localhost:5000/echo')
+.type('application/x-dog')
+.send('hello this is dog')
+.buffer(false)
+.end(function(err, res){
+  assert(null == err);
+  assert(null == res.text);
+  res.body.should.eql({});
+  var buf = '';
+  res.setEncoding('utf8');
+  res.on('data', function(chunk){ buf += chunk });
+  res.on('end', function(){
+    buf.should.equal('hello this is dog');
+    done();
+  });
+});
+
+
+
+

.agent()

+
+
should return the defaut agent
+
var req = request.post('http://localhost:5000/echo');
+req.agent().should.equal(false);
+done();
+
+
+
+

.agent(undefined)

+
+
should set an agent to undefined and ensure it is chainable
+
var req = request.get('http://localhost:5000/echo');
+var ret = req.agent(undefined);
+ret.should.equal(req);
+assert(req.agent() === undefined);
+done();
+
+
+
+

.agent(new http.Agent())

+
+
should set passed agent
+
var http = require('http');
+var req = request.get('http://localhost:5000/echo');
+var agent = new http.Agent();
+var ret = req.agent(agent);
+ret.should.equal(req);
+req.agent().should.equal(agent)
+done();
+
+
+
+

with a content type other than application/json or text/*

+
+
should disable buffering
+
request
+.post('http://localhost:5000/echo')
+.type('application/x-dog')
+.send('hello this is dog')
+.end(function(err, res){
+  assert(null == err);
+  assert(null == res.text);
+  res.body.should.eql({});
+  var buf = '';
+  res.setEncoding('utf8');
+  res.buffered.should.be.false;
+  res.on('data', function(chunk){ buf += chunk });
+  res.on('end', function(){
+    buf.should.equal('hello this is dog');
+    done();
+  });
+});
+
+
+
+

content-length

+
+
should be set to the byte length of a non-buffer object
+
var decoder = new StringDecoder('utf8');
+var img = fs.readFileSync(__dirname + '/fixtures/test.png');
+img = decoder.write(img);
+request
+.post('http://localhost:5000/echo')
+.type('application/x-image')
+.send(img)
+.buffer(false)
+.end(function(err, res){
+  assert(null == err);
+  assert(!res.buffered);
+  assert(res.header['content-length'] == Buffer.byteLength(img));
+  done();
+});
+
should be set to the length of a buffer object
+
var img = fs.readFileSync(__dirname + '/fixtures/test.png');
+request
+.post('http://localhost:5000/echo')
+.type('application/x-image')
+.send(img)
+.buffer(true)
+.end(function(err, res){
+  assert(null == err);
+  assert(res.buffered);
+  assert(res.header['content-length'] == img.length);
+  done();
+});
+
+
+
+
+
+

req.set("Content-Type", contentType)

+
+
should work with just the contentType component
+
request
+.post('http://localhost:3005/echo')
+.set('Content-Type', 'application/json')
+.send({ name: 'tobi' })
+.end(function(err, res){
+  assert(!err);
+  done();
+});
+
should work with the charset component
+
request
+.post('http://localhost:3005/echo')
+.set('Content-Type', 'application/json; charset=utf-8')
+.send({ name: 'tobi' })
+.end(function(err, res){
+  assert(!err);
+  done();
+});
+
+
+
+

exports

+
+
should expose Part
+
request.Part.should.be.a.function;
+
should expose .protocols
+
Object.keys(request.protocols)
+  .should.eql(['http:', 'https:']);
+
should expose .serialize
+
Object.keys(request.serialize)
+  .should.eql(['application/x-www-form-urlencoded', 'application/json']);
+
should expose .parse
+
Object.keys(request.parse)
+  .should.eql(['application/x-www-form-urlencoded', 'application/json', 'text', 'image']);
+
+
+
+

flags

+
+
+

with 4xx response

+
+
should set res.error and res.clientError
+
request
+.get('http://localhost:3004/notfound')
+.end(function(err, res){
+  assert(err);
+  assert(!res.ok, 'response should not be ok');
+  assert(res.error, 'response should be an error');
+  assert(res.clientError, 'response should be a client error');
+  assert(!res.serverError, 'response should not be a server error');
+  done();
+});
+
+
+
+

with 5xx response

+
+
should set res.error and res.serverError
+
request
+.get('http://localhost:3004/error')
+.end(function(err, res){
+  assert(err);
+  assert(!res.ok, 'response should not be ok');
+  assert(!res.notFound, 'response should not be notFound');
+  assert(res.error, 'response should be an error');
+  assert(!res.clientError, 'response should not be a client error');
+  assert(res.serverError, 'response should be a server error');
+  done();
+});
+
+
+
+

with 404 Not Found

+
+
should res.notFound
+
request
+.get('http://localhost:3004/notfound')
+.end(function(err, res){
+  assert(err);
+  assert(res.notFound, 'response should be .notFound');
+  done();
+});
+
+
+
+

with 400 Bad Request

+
+
should set req.badRequest
+
request
+.get('http://localhost:3004/bad-request')
+.end(function(err, res){
+  assert(err);
+  assert(res.badRequest, 'response should be .badRequest');
+  done();
+});
+
+
+
+

with 401 Bad Request

+
+
should set res.unauthorized
+
request
+.get('http://localhost:3004/unauthorized')
+.end(function(err, res){
+  assert(err);
+  assert(res.unauthorized, 'response should be .unauthorized');
+  done();
+});
+
+
+
+

with 406 Not Acceptable

+
+
should set res.notAcceptable
+
request
+.get('http://localhost:3004/not-acceptable')
+.end(function(err, res){
+  assert(err);
+  assert(res.notAcceptable, 'response should be .notAcceptable');
+  done();
+});
+
+
+
+

with 204 No Content

+
+
should set res.noContent
+
request
+.get('http://localhost:3004/no-content')
+.end(function(err, res){
+  assert(!err);
+  assert(res.noContent, 'response should be .noContent');
+  done();
+});
+
+
+
+
+
+

req.send(Object) as "form"

+
+
+

with req.type() set to form

+
+
should send x-www-form-urlencoded data
+
request
+.post('http://localhost:3002/echo')
+.type('form')
+.send({ name: 'tobi' })
+.end(function(err, res){
+  res.header['content-type'].should.equal('application/x-www-form-urlencoded');
+  res.text.should.equal('name=tobi');
+  done();
+});
+
+
+
+

when called several times

+
+
should merge the objects
+
request
+.post('http://localhost:3002/echo')
+.type('form')
+.send({ name: { first: 'tobi', last: 'holowaychuk' } })
+.send({ age: '1' })
+.end(function(err, res){
+  res.header['content-type'].should.equal('application/x-www-form-urlencoded');
+  res.text.should.equal('name%5Bfirst%5D=tobi&name%5Blast%5D=holowaychuk&age=1');
+  done();
+});
+
+
+
+
+
+

req.send(String)

+
+
should default to "form"
+
request
+.post('http://localhost:3002/echo')
+.send('user[name]=tj')
+.send('user[email]=tj@vision-media.ca')
+.end(function(err, res){
+  res.header['content-type'].should.equal('application/x-www-form-urlencoded');
+  res.body.should.eql({ user: { name: 'tj', email: 'tj@vision-media.ca' } });
+  done();
+})
+
+
+
+

res.body

+
+
+

application/x-www-form-urlencoded

+
+
should parse the body
+
request
+.get('http://localhost:3002/form-data')
+.end(function(err, res){
+  res.text.should.equal('pet[name]=manny');
+  res.body.should.eql({ pet: { name: 'manny' }});
+  done();
+});
+
+
+
+
+
+

https

+
+
+

request

+
+
should give a good response
+
request
+.get('https://localhost:8443/')
+.ca(cert)
+.end(function(err, res){
+  assert(res.ok);
+  assert('Safe and secure!' === res.text);
+  done();
+});
+
+
+
+

.agent

+
+
should be able to make multiple requests without redefining the certificate
+
var agent = request.agent({ca: cert});
+agent
+.get('https://localhost:8443/')
+.end(function(err, res){
+  assert(res.ok);
+  assert('Safe and secure!' === res.text);
+  agent
+  .get(url.parse('https://localhost:8443/'))
+  .end(function(err, res){
+    assert(res.ok);
+    assert('Safe and secure!' === res.text);
+    done();
+  });
+});
+
+
+
+
+
+

res.body

+
+
+

image/png

+
+
should parse the body
+
request
+.get('http://localhost:3011/image')
+.end(function(err, res){
+  (res.body.length - img.length).should.equal(0);
+  done();
+});
+
+
+
+
+
+

zlib

+
+
should deflate the content
+
request
+  .get('http://localhost:3080')
+  .end(function(err, res){
+    res.should.have.status(200);
+    res.text.should.equal(subject);
+    res.headers['content-length'].should.be.below(subject.length);
+    done();
+  });
+
should handle corrupted responses
+
request
+  .get('http://localhost:3080/corrupt')
+  .end(function(err, res){
+    assert(err, 'missing error');
+    assert(!res, 'response should not be defined');
+    done();
+  });
+
+

without encoding set

+
+
should emit buffers
+
request
+  .get('http://localhost:3080/binary')
+  .end(function(err, res){
+    res.should.have.status(200);
+    res.headers['content-length'].should.be.below(subject.length);
+    res.on('data', function(chunk){
+      chunk.should.have.length(subject.length);
+    });
+    res.on('end', done);
+  });
+
+
+
+
+
+

req.send(Object) as "json"

+
+
should default to json
+
request
+.post('http://localhost:3005/echo')
+.send({ name: 'tobi' })
+.end(function(err, res){
+  res.should.be.json
+  res.text.should.equal('{"name":"tobi"}');
+  done();
+});
+
should work with arrays
+
request
+.post('http://localhost:3005/echo')
+.send([1,2,3])
+.end(function(err, res){
+  res.should.be.json
+  res.text.should.equal('[1,2,3]');
+  done();
+});
+
should work with value null
+
request
+.post('http://localhost:3005/echo')
+.type('json')
+.send('null')
+.end(function(err, res){
+  res.should.be.json
+  assert(res.body === null);
+  done();
+});
+
should work with value false
+
request
+.post('http://localhost:3005/echo')
+.type('json')
+.send('false')
+.end(function(err, res){
+  res.should.be.json
+  res.body.should.equal(false);
+  done();
+});
+
should work with value 0
+
request
+.post('http://localhost:3005/echo')
+.type('json')
+.send('0')
+.end(function(err, res){
+  res.should.be.json
+  res.body.should.equal(0);
+  done();
+});
+
should work with empty string value
+
request
+.post('http://localhost:3005/echo')
+.type('json')
+.send('""')
+.end(function(err, res){
+  res.should.be.json
+  res.body.should.equal("");
+  done();
+});
+
should work with GET
+
request
+.get('http://localhost:3005/echo')
+.send({ tobi: 'ferret' })
+.end(function(err, res){
+  res.should.be.json
+  res.text.should.equal('{"tobi":"ferret"}');
+  done();
+});
+
should work with vendor MIME type
+
request
+.post('http://localhost:3005/echo')
+.set('Content-Type', 'application/vnd.example+json')
+.send({ name: 'vendor' })
+.end(function(err, res){
+  res.text.should.equal('{"name":"vendor"}');
+  done();
+});
+
+

when called several times

+
+
should merge the objects
+
request
+.post('http://localhost:3005/echo')
+.send({ name: 'tobi' })
+.send({ age: 1 })
+.end(function(err, res){
+  res.should.be.json
+  res.text.should.equal('{"name":"tobi","age":1}');
+  done();
+});
+
+
+
+
+
+

res.body

+
+
+

application/json

+
+
should parse the body
+
request
+.get('http://localhost:3005/json')
+.end(function(err, res){
+  res.text.should.equal('{"name":"manny"}');
+  res.body.should.eql({ name: 'manny' });
+  done();
+});
+
+
+
+

HEAD requests

+
+
should not throw a parse error
+
request
+.head('http://localhost:3005/json')
+.end(function(err, res){
+  assert(err === null);
+  assert(res.text === undefined)
+  assert(Object.keys(res.body).length === 0)
+  done();
+});
+
+
+
+

Invalid JSON response

+
+
should return the raw response
+
request
+.get('http://localhost:3005/invalid-json')
+.end(function(err, res){
+  assert.deepEqual(err.rawResponse, ")]}', {'header':{'code':200,'text':'OK','version':'1.0'},'data':'some data'}");
+  done();
+});
+
+
+
+

No content

+
+
should not throw a parse error
+
request
+.get('http://localhost:3005/no-content')
+.end(function(err, res){
+  assert(err === null);
+  assert(res.text === '');
+  assert(Object.keys(res.body).length === 0);
+  done();
+});
+
+
+
+

application/json+hal

+
+
should parse the body
+
request
+.get('http://localhost:3005/json-hal')
+.end(function(err, res){
+  if (err) return done(err);
+  res.text.should.equal('{"name":"hal 5000"}');
+  res.body.should.eql({ name: 'hal 5000' });
+  done();
+});
+
+
+
+

vnd.collection+json

+
+
should parse the body
+
request
+.get('http://localhost:3005/collection-json')
+.end(function(err, res){
+  res.text.should.equal('{"name":"chewbacca"}');
+  res.body.should.eql({ name: 'chewbacca' });
+  done();
+});
+
+
+
+
+
+

Request

+
+
+

#attach(name, path, filename)

+
+
should use the custom filename
+
request
+.post(':3005/echo')
+.attach('document', 'test/node/fixtures/user.html', 'doc.html')
+.end(function(err, res){
+  if (err) return done(err);
+  var html = res.files.document;
+  html.name.should.equal('doc.html');
+  html.type.should.equal('text/html');
+  read(html.path).should.equal('<h1>name</h1>');
+  done();
+})
+
should fire progress event
+
var loaded = 0;
+var total = 0;
+request
+.post(':3005/echo')
+.attach('document', 'test/node/fixtures/user.html')
+.on('progress', function (event) {
+  total = event.total;
+  loaded = event.loaded;
+})
+.end(function(err, res){
+  if (err) return done(err);
+  var html = res.files.document;
+  html.name.should.equal('user.html');
+  html.type.should.equal('text/html');
+  read(html.path).should.equal('<h1>name</h1>');
+  total.should.equal(221);
+  loaded.should.equal(221);
+  done();
+})
+
+
+
+
+
+

with network error

+
+
should error
+
request
+.get('http://localhost:' + this.port + '/')
+.end(function(err, res){
+  assert(err, 'expected an error');
+  done();
+});
+
+
+
+

request

+
+
+

not modified

+
+
should start with 200
+
request
+.get('http://localhost:3008/')
+.end(function(err, res){
+  res.should.have.status(200)
+  res.text.should.match(/^\d+$/);
+  ts = +res.text;
+  done();
+});
+
should then be 304
+
request
+.get('http://localhost:3008/')
+.set('If-Modified-Since', new Date(ts).toUTCString())
+.end(function(err, res){
+  res.should.have.status(304)
+  // res.text.should.be.empty
+  done();
+});
+
+
+
+
+
+

req.parse(fn)

+
+
should take precedence over default parsers
+
request
+.get('http://localhost:3033/manny')
+.parse(request.parse['application/json'])
+.end(function(err, res){
+  assert(res.ok);
+  assert('{"name":"manny"}' == res.text);
+  assert('manny' == res.body.name);
+  done();
+});
+
should be the only parser
+
request
+.get('http://localhost:3033/image')
+.parse(function(res, fn) {
+  res.on('data', function() {});
+})
+.end(function(err, res){
+  assert(res.ok);
+  assert(res.text === undefined);
+  res.body.should.eql({});
+  done();
+});
+
should emit error if parser throws
+
request
+.get('http://localhost:3033/manny')
+.parse(function() {
+  throw new Error('I am broken');
+})
+.on('error', function(err) {
+  err.message.should.equal('I am broken');
+  done();
+})
+.end();
+
should emit error if parser returns an error
+
request
+.get('http://localhost:3033/manny')
+.parse(function(res, fn) {
+  fn(new Error('I am broken'));
+})
+.on('error', function(err) {
+  err.message.should.equal('I am broken');
+  done();
+})
+.end()
+
should not emit error on chunked json
+
request
+.get('http://localhost:3033/chunked-json')
+.end(function(err){
+  assert(!err);
+  done();
+});
+
should not emit error on aborted chunked json
+
var req = request
+.get('http://localhost:3033/chunked-json')
+.end(function(err){
+  assert(!err);
+  done();
+});
+setTimeout(function(){req.abort()},50);
+
+
+
+

pipe on redirect

+
+
should follow Location
+
var stream = fs.createWriteStream('test/node/fixtures/pipe.txt');
+var redirects = [];
+var req = request
+  .get('http://localhost:3012/')
+  .on('redirect', function (res) {
+    redirects.push(res.headers.location);
+  })
+  .on('end', function () {
+    var arr = [];
+    arr.push('/movies');
+    arr.push('/movies/all');
+    arr.push('/movies/all/0');
+    redirects.should.eql(arr);
+    fs.readFileSync('test/node/fixtures/pipe.txt', 'utf8').should.eql('first movie page');
+    done();
+  });
+  req.pipe(stream);
+
+
+
+

request pipe

+
+
should act as a writable stream
+
var req = request.post('http://localhost:3020');
+var stream = fs.createReadStream('test/node/fixtures/user.json');
+req.type('json');
+req.on('response', function(res){
+  res.body.should.eql({ name: 'tobi' });
+  done();
+});
+stream.pipe(req);
+
should act as a readable stream
+
var stream = fs.createWriteStream('test/node/fixtures/tmp.json');
+var req = request.get('http://localhost:3025');
+req.type('json');
+req.on('end', function(){
+  JSON.parse(fs.readFileSync('test/node/fixtures/tmp.json', 'utf8')).should.eql({ name: 'tobi' });
+  done();
+});
+req.pipe(stream);
+
+
+
+

req.query(String)

+
+
should supply uri malformed error to the callback
+
request
+.get('http://localhost:3006')
+.query('name=toby')
+.query('a=\uD800')
+.query({ b: '\uD800' })
+.end(function(err, res){
+  assert(err instanceof Error);
+  assert('URIError' == err.name);
+  done();
+});
+
should support passing in a string
+
request
+.del('http://localhost:3006')
+.query('name=t%F6bi')
+.end(function(err, res){
+  res.body.should.eql({ name: 't%F6bi' });
+  done();
+});
+
should work with url query-string and string for query
+
request
+.del('http://localhost:3006/?name=tobi')
+.query('age=2%20')
+.end(function(err, res){
+  res.body.should.eql({ name: 'tobi', age: '2 ' });
+  done();
+});
+
should support compound elements in a string
+
request
+  .del('http://localhost:3006/')
+  .query('name=t%F6bi&age=2')
+  .end(function(err, res){
+    res.body.should.eql({ name: 't%F6bi', age: '2' });
+    done();
+  });
+
should work when called multiple times with a string
+
request
+.del('http://localhost:3006/')
+.query('name=t%F6bi')
+.query('age=2%F6')
+.end(function(err, res){
+  res.body.should.eql({ name: 't%F6bi', age: '2%F6' });
+  done();
+});
+
should work with normal `query` object and query string
+
request
+.del('http://localhost:3006/')
+.query('name=t%F6bi')
+.query({ age: '2' })
+.end(function(err, res){
+  res.body.should.eql({ name: 't%F6bi', age: '2' });
+  done();
+});
+
+
+
+

req.query(Object)

+
+
should construct the query-string
+
request
+.del('http://localhost:3006/')
+.query({ name: 'tobi' })
+.query({ order: 'asc' })
+.query({ limit: ['1', '2'] })
+.end(function(err, res){
+  res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] });
+  done();
+});
+
should not error on dates
+
var date = new Date(0);
+request
+.del('http://localhost:3006/')
+.query({ at: date })
+.end(function(err, res){
+  assert(date.toISOString() == res.body.at);
+  done();
+});
+
should work after setting header fields
+
request
+.del('http://localhost:3006/')
+.set('Foo', 'bar')
+.set('Bar', 'baz')
+.query({ name: 'tobi' })
+.query({ order: 'asc' })
+.query({ limit: ['1', '2'] })
+.end(function(err, res){
+  res.body.should.eql({ name: 'tobi', order: 'asc', limit: ['1', '2'] });
+  done();
+});
+
should append to the original query-string
+
request
+.del('http://localhost:3006/?name=tobi')
+.query({ order: 'asc' })
+.end(function(err, res) {
+  res.body.should.eql({ name: 'tobi', order: 'asc' });
+  done();
+});
+
should retain the original query-string
+
request
+.del('http://localhost:3006/?name=tobi')
+.end(function(err, res) {
+  res.body.should.eql({ name: 'tobi' });
+  done();
+});
+
+
+
+

request.get

+
+
+

on 301 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .get('http://localhost:3210/test-301')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 302 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .get('http://localhost:3210/test-302')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 303 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .get('http://localhost:3210/test-303')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 307 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .get('http://localhost:3210/test-307')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 308 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .get('http://localhost:3210/test-308')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+
+
+

request.post

+
+
+

on 301 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .post('http://localhost:3210/test-301')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 302 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .post('http://localhost:3210/test-302')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 303 redirect

+
+
should follow Location with a GET request
+
var req = request
+  .post('http://localhost:3210/test-303')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('GET');
+    done();
+  });
+
+
+
+

on 307 redirect

+
+
should follow Location with a POST request
+
var req = request
+  .post('http://localhost:3210/test-307')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('POST');
+    done();
+  });
+
+
+
+

on 308 redirect

+
+
should follow Location with a POST request
+
var req = request
+  .post('http://localhost:3210/test-308')
+  .redirects(1)
+  .end(function(err, res){
+    req.req._headers.host.should.eql('localhost:3211');
+    res.status.should.eql(200);
+    res.text.should.eql('POST');
+    done();
+  });
+
+
+
+
+
+

request

+
+
+

on redirect

+
+
should follow Location
+
var redirects = [];
+request
+.get('http://localhost:3003/')
+.on('redirect', function(res){
+  redirects.push(res.headers.location);
+})
+.end(function(err, res){
+  var arr = [];
+  arr.push('/movies');
+  arr.push('/movies/all');
+  arr.push('/movies/all/0');
+  redirects.should.eql(arr);
+  res.text.should.equal('first movie page');
+  done();
+});
+
should retain header fields
+
request
+.get('http://localhost:3003/header')
+.set('X-Foo', 'bar')
+.end(function(err, res){
+  res.body.should.have.property('x-foo', 'bar');
+  done();
+});
+
should remove Content-* fields
+
request
+.post('http://localhost:3003/header')
+.type('txt')
+.set('X-Foo', 'bar')
+.set('X-Bar', 'baz')
+.send('hey')
+.end(function(err, res){
+  res.body.should.have.property('x-foo', 'bar');
+  res.body.should.have.property('x-bar', 'baz');
+  res.body.should.not.have.property('content-type');
+  res.body.should.not.have.property('content-length');
+  res.body.should.not.have.property('transfer-encoding');
+  done();
+});
+
should retain cookies
+
request
+.get('http://localhost:3003/header')
+.set('Cookie', 'foo=bar;')
+.end(function(err, res){
+  res.body.should.have.property('cookie', 'foo=bar;');
+  done();
+});
+
should preserve timeout across redirects
+
request
+.get('http://localhost:3003/movies/random')
+.timeout(250)
+.end(function(err, res){
+  assert(err instanceof Error, 'expected an error');
+  err.should.have.property('timeout', 250);
+  done();
+});
+
should not resend query parameters
+
var redirects = [];
+var query = [];
+request
+.get('http://localhost:3003/?foo=bar')
+.on('redirect', function(res){
+  query.push(res.headers.query);
+  redirects.push(res.headers.location);
+})
+.end(function(err, res){
+  var arr = [];
+  arr.push('/movies');
+  arr.push('/movies/all');
+  arr.push('/movies/all/0');
+  redirects.should.eql(arr);
+  res.text.should.equal('first movie page');
+  query.should.eql(['{"foo":"bar"}', '{}', '{}']);
+  res.headers.query.should.eql('{}');
+  done();
+});
+
should handle no location header
+
request
+.get('http://localhost:3003/bad-redirect')
+.end(function(err, res){
+  err.message.should.equal('No location header for redirect');
+  done();
+});
+
+

when relative

+
+
should redirect to a sibling path
+
var redirects = [];
+request
+.get('http://localhost:3003/relative')
+.on('redirect', function(res){
+  redirects.push(res.headers.location);
+})
+.end(function(err, res){
+  var arr = [];
+  redirects.should.eql(['tobi']);
+  res.text.should.equal('tobi');
+  done();
+});
+
should redirect to a parent path
+
var redirects = [];
+request
+.get('http://localhost:3003/relative/sub')
+.on('redirect', function(res){
+  redirects.push(res.headers.location);
+})
+.end(function(err, res){
+  var arr = [];
+  redirects.should.eql(['../tobi']);
+  res.text.should.equal('tobi');
+  done();
+});
+
+
+
+
+
+

req.redirects(n)

+
+
should alter the default number of redirects to follow
+
var redirects = [];
+request
+.get('http://localhost:3003/')
+.redirects(2)
+.on('redirect', function(res){
+  redirects.push(res.headers.location);
+})
+.end(function(err, res){
+  var arr = [];
+  assert(res.redirect, 'res.redirect');
+  arr.push('/movies');
+  arr.push('/movies/all');
+  redirects.should.eql(arr);
+  res.text.should.match(/Moved Temporarily|Found/);
+  done();
+});
+
+
+
+

on POST

+
+
should redirect as GET
+
var redirects = [];
+request
+.post('http://localhost:3003/movie')
+.send({ name: 'Tobi' })
+.redirects(2)
+.on('redirect', function(res){
+  redirects.push(res.headers.location);
+})
+.end(function(err, res){
+  var arr = [];
+  arr.push('/movies/all/0');
+  redirects.should.eql(arr);
+  res.text.should.equal('first movie page');
+  done();
+});
+
+
+
+

on 303

+
+
should redirect with same method
+
request
+.put('http://localhost:3003/redirect-303')
+.send({msg: "hello"})
+.redirects(1)
+.on('redirect', function(res) {
+  res.headers.location.should.equal('/reply-method')
+})
+.end(function(err, res){
+  res.text.should.equal('method=get');
+  done();
+})
+
+
+
+

on 307

+
+
should redirect with same method
+
request
+.put('http://localhost:3003/redirect-307')
+.send({msg: "hello"})
+.redirects(1)
+.on('redirect', function(res) {
+  res.headers.location.should.equal('/reply-method')
+})
+.end(function(err, res){
+  res.text.should.equal('method=put');
+  done();
+})
+
+
+
+

on 308

+
+
should redirect with same method
+
request
+.put('http://localhost:3003/redirect-308')
+.send({msg: "hello"})
+.redirects(1)
+.on('redirect', function(res) {
+  res.headers.location.should.equal('/reply-method')
+})
+.end(function(err, res){
+  res.text.should.equal('method=put');
+  done();
+})
+
+
+
+
+
+

response

+
+
should act as a readable stream
+
var req = request
+  .get('http://localhost:3025')
+  .buffer(false);
+req.end(function(err,res){
+  if (err) return done(err);
+  var trackEndEvent = 0;
+  var trackCloseEvent = 0;
+  res.on('end',function(){
+    trackEndEvent++;
+    trackEndEvent.should.equal(1);
+    trackCloseEvent.should.equal(0);  // close should not have been called
+    done();
+  });
+  res.on('close',function(){
+    trackCloseEvent++;
+  });
+
+  (function(){ res.pause() }).should.not.throw();
+  (function(){ res.resume() }).should.not.throw();
+  (function(){ res.destroy() }).should.not.throw();
+});
+
+
+
+

.timeout(ms)

+
+
+

when timeout is exceeded

+
+
should error
+
request
+.get('http://localhost:3009/500')
+.timeout(150)
+.end(function(err, res){
+  assert(err, 'expected an error');
+  assert('number' == typeof err.timeout, 'expected an error with .timeout');
+  assert('ECONNABORTED' == err.code, 'expected abort error code')
+  done();
+});
+
+
+
+
+
+

res.toError()

+
+
should return an Error
+
request
+.get('http://localhost:' + server.address().port)
+.end(function(err, res){
+  var err = res.toError();
+  assert(err.status == 400);
+  assert(err.method == 'GET');
+  assert(err.path == '/');
+  assert(err.message == 'cannot GET / (400)');
+  assert(err.text == 'invalid json');
+  done();
+});
+
+
+
+

req.get()

+
+
should set a default user-agent
+
request
+.get('http://localhost:3345/ua')
+.end(function(err, res){
+  assert(res.headers);
+  assert(res.headers['user-agent']);
+  assert(/^node-superagent\/\d+\.\d+\.\d+$/.test(res.headers['user-agent']));
+  done();
+});
+
should be able to override user-agent
+
request
+.get('http://localhost:3345/ua')
+.set('User-Agent', 'foo/bar')
+.end(function(err, res){
+  assert(res.headers);
+  assert(res.headers['user-agent'] == 'foo/bar');
+  done();
+});
+
should be able to wipe user-agent
+
request
+.get('http://localhost:3345/ua')
+.unset('User-Agent')
+.end(function(err, res){
+  assert(res.headers);
+  assert(res.headers['user-agent'] == void 0);
+  done();
+});
+
+
+
+

utils.type(str)

+
+
should return the mime type
+
utils.type('application/json; charset=utf-8')
+  .should.equal('application/json');
+utils.type('application/json')
+  .should.equal('application/json');
+
+
+
+

utils.params(str)

+
+
should return the field parameters
+
var str = 'application/json; charset=utf-8; foo  = bar';
+var obj = utils.params(str);
+obj.charset.should.equal('utf-8');
+obj.foo.should.equal('bar');
+var str = 'application/json';
+utils.params(str).should.eql({});
+
+
+
+

utils.parseLinks(str)

+
+
should parse links
+
var str = '<https://api.github.com/repos/visionmedia/mocha/issues?page=2>; rel="next", <https://api.github.com/repos/visionmedia/mocha/issues?page=5>; rel="last"';
+var ret = utils.parseLinks(str);
+ret.next.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=2');
+ret.last.should.equal('https://api.github.com/repos/visionmedia/mocha/issues?page=5');
+
+
+
+ Fork me on GitHub + + \ No newline at end of file diff --git a/node_modules/chai-http/node_modules/superagent/lib/client.js b/node_modules/chai-http/node_modules/superagent/lib/client.js new file mode 100644 index 0000000..9454b15 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/client.js @@ -0,0 +1,974 @@ +/** + * Root reference for iframes. + */ + +var root; +if (typeof window !== 'undefined') { // Browser window + root = window; +} else if (typeof self !== 'undefined') { // Web Worker + root = self; +} else { // Other environments + console.warn("Using browser-only version of superagent in non-browser environment"); + root = this; +} + +var Emitter = require('emitter'); +var requestBase = require('./request-base'); +var isObject = require('./is-object'); + +/** + * Noop. + */ + +function noop(){}; + +/** + * Expose `request`. + */ + +var request = module.exports = require('./request').bind(null, Request); + +/** + * Determine XHR. + */ + +request.getXHR = function () { + if (root.XMLHttpRequest + && (!root.location || 'file:' != root.location.protocol + || !root.ActiveXObject)) { + return new XMLHttpRequest; + } else { + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {} + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {} + } + throw Error("Browser-only verison of superagent could not find XHR"); +}; + +/** + * Removes leading and trailing whitespace, added to support IE. + * + * @param {String} s + * @return {String} + * @api private + */ + +var trim = ''.trim + ? function(s) { return s.trim(); } + : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); }; + +/** + * Serialize the given `obj`. + * + * @param {Object} obj + * @return {String} + * @api private + */ + +function serialize(obj) { + if (!isObject(obj)) return obj; + var pairs = []; + for (var key in obj) { + if (null != obj[key]) { + pushEncodedKeyValuePair(pairs, key, obj[key]); + } + } + return pairs.join('&'); +} + +/** + * Helps 'serialize' with serializing arrays. + * Mutates the pairs array. + * + * @param {Array} pairs + * @param {String} key + * @param {Mixed} val + */ + +function pushEncodedKeyValuePair(pairs, key, val) { + if (Array.isArray(val)) { + return val.forEach(function(v) { + pushEncodedKeyValuePair(pairs, key, v); + }); + } else if (isObject(val)) { + for(var subkey in val) { + pushEncodedKeyValuePair(pairs, key + '[' + subkey + ']', val[subkey]); + } + return; + } + pairs.push(encodeURIComponent(key) + + '=' + encodeURIComponent(val)); +} + +/** + * Expose serialization method. + */ + + request.serializeObject = serialize; + + /** + * Parse the given x-www-form-urlencoded `str`. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseString(str) { + var obj = {}; + var pairs = str.split('&'); + var pair; + var pos; + + for (var i = 0, len = pairs.length; i < len; ++i) { + pair = pairs[i]; + pos = pair.indexOf('='); + if (pos == -1) { + obj[decodeURIComponent(pair)] = ''; + } else { + obj[decodeURIComponent(pair.slice(0, pos))] = + decodeURIComponent(pair.slice(pos + 1)); + } + } + + return obj; +} + +/** + * Expose parser. + */ + +request.parseString = parseString; + +/** + * Default MIME type map. + * + * superagent.types.xml = 'application/xml'; + * + */ + +request.types = { + html: 'text/html', + json: 'application/json', + xml: 'application/xml', + urlencoded: 'application/x-www-form-urlencoded', + 'form': 'application/x-www-form-urlencoded', + 'form-data': 'application/x-www-form-urlencoded' +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + + request.serialize = { + 'application/x-www-form-urlencoded': serialize, + 'application/json': JSON.stringify + }; + + /** + * Default parsers. + * + * superagent.parse['application/xml'] = function(str){ + * return { object parsed from str }; + * }; + * + */ + +request.parse = { + 'application/x-www-form-urlencoded': parseString, + 'application/json': JSON.parse +}; + +/** + * Parse the given header `str` into + * an object containing the mapped fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function parseHeader(str) { + var lines = str.split(/\r?\n/); + var fields = {}; + var index; + var line; + var field; + var val; + + lines.pop(); // trailing CRLF + + for (var i = 0, len = lines.length; i < len; ++i) { + line = lines[i]; + index = line.indexOf(':'); + field = line.slice(0, index).toLowerCase(); + val = trim(line.slice(index + 1)); + fields[field] = val; + } + + return fields; +} + +/** + * Check if `mime` is json or has +json structured syntax suffix. + * + * @param {String} mime + * @return {Boolean} + * @api private + */ + +function isJSON(mime) { + return /[\/+]json\b/.test(mime); +} + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +function type(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +function params(str){ + return str.split(/ *; */).reduce(function(obj, str){ + var parts = str.split(/ *= */), + key = parts.shift(), + val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * Examples: + * + * Aliasing `superagent` as `request` is nice: + * + * request = superagent; + * + * We can use the promise-like API, or pass callbacks: + * + * request.get('/').end(function(res){}); + * request.get('/', function(res){}); + * + * Sending data can be chained: + * + * request + * .post('/user') + * .send({ name: 'tj' }) + * .end(function(res){}); + * + * Or passed to `.send()`: + * + * request + * .post('/user') + * .send({ name: 'tj' }, function(res){}); + * + * Or passed to `.post()`: + * + * request + * .post('/user', { name: 'tj' }) + * .end(function(res){}); + * + * Or further reduced to a single call for simple cases: + * + * request + * .post('/user', { name: 'tj' }, function(res){}); + * + * @param {XMLHTTPRequest} xhr + * @param {Object} options + * @api private + */ + +function Response(req, options) { + options = options || {}; + this.req = req; + this.xhr = this.req.xhr; + // responseText is accessible only if responseType is '' or 'text' and on older browsers + this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined') + ? this.xhr.responseText + : null; + this.statusText = this.req.xhr.statusText; + this._setStatusProperties(this.xhr.status); + this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders()); + // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but + // getResponseHeader still works. so we get content-type even if getting + // other headers fails. + this.header['content-type'] = this.xhr.getResponseHeader('content-type'); + this._setHeaderProperties(this.header); + this.body = this.req.method != 'HEAD' + ? this._parseBody(this.text ? this.text : this.xhr.response) + : null; +} + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype._setHeaderProperties = function(header){ + // content-type + var ct = this.header['content-type'] || ''; + this.type = type(ct); + + // params + var obj = params(ct); + for (var key in obj) this[key] = obj[key]; +}; + +/** + * Parse the given body `str`. + * + * Used for auto-parsing of bodies. Parsers + * are defined on the `superagent.parse` object. + * + * @param {String} str + * @return {Mixed} + * @api private + */ + +Response.prototype._parseBody = function(str){ + var parse = request.parse[this.type]; + if (!parse && isJSON(this.type)) { + parse = request.parse['application/json']; + } + return parse && str && (str.length || str instanceof Object) + ? parse(str) + : null; +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype._setStatusProperties = function(status){ + // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + if (status === 1223) { + status = 204; + } + + var type = status / 100 | 0; + + // status / class + this.status = this.statusCode = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.notFound = 404 == status; + this.forbidden = 403 == status; +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var url = req.url; + + var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.method = method; + err.url = url; + + return err; +}; + +/** + * Expose `Response`. + */ + +request.Response = Response; + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String} url + * @api public + */ + +function Request(method, url) { + var self = this; + this._query = this._query || []; + this.method = method; + this.url = url; + this.header = {}; // preserves header name case + this._header = {}; // coerces header names to lowercase + this.on('end', function(){ + var err = null; + var res = null; + + try { + res = new Response(self); + } catch(e) { + err = new Error('Parser is unable to parse the response'); + err.parse = true; + err.original = e; + // issue #675: return the raw response if the response parsing fails + err.rawResponse = self.xhr && self.xhr.responseText ? self.xhr.responseText : null; + // issue #876: return the http status code if the response parsing fails + err.statusCode = self.xhr && self.xhr.status ? self.xhr.status : null; + return self.callback(err); + } + + self.emit('response', res); + + var new_err; + try { + if (res.status < 200 || res.status >= 300) { + new_err = new Error(res.statusText || 'Unsuccessful HTTP response'); + new_err.original = err; + new_err.response = res; + new_err.status = res.status; + } + } catch(e) { + new_err = e; // #985 touching res may cause INVALID_STATE_ERR on old Android + } + + // #1000 don't catch errors from the callback to avoid double calling it + if (new_err) { + self.callback(new_err, res); + } else { + self.callback(null, res); + } + }); +} + +/** + * Mixin `Emitter` and `requestBase`. + */ + +Emitter(Request.prototype); +for (var key in requestBase) { + Request.prototype[key] = requestBase[key]; +} + +/** + * Set Content-Type to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.xml = 'application/xml'; + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('application/xml') + * .send(xmlstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + this.set('Content-Type', request.types[type] || type); + return this; +}; + +/** + * Set responseType to `val`. Presently valid responseTypes are 'blob' and + * 'arraybuffer'. + * + * Examples: + * + * req.get('/') + * .responseType('blob') + * .end(callback); + * + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.responseType = function(val){ + this._responseType = val; + return this; +}; + +/** + * Set Accept to `type`, mapping values from `request.types`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + this.set('Accept', request.types[type] || type); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * @param {String} user + * @param {String} pass + * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic') + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass, options){ + if (!options) { + options = { + type: 'basic' + } + } + + switch (options.type) { + case 'basic': + var str = btoa(user + ':' + pass); + this.set('Authorization', 'Basic ' + str); + break; + + case 'auto': + this.username = user; + this.password = pass; + break; + } + return this; +}; + +/** +* Add query-string `val`. +* +* Examples: +* +* request.get('/shoes') +* .query('size=10') +* .query({ color: 'blue' }) +* +* @param {Object|String} val +* @return {Request} for chaining +* @api public +*/ + +Request.prototype.query = function(val){ + if ('string' != typeof val) val = serialize(val); + if (val) this._query.push(val); + return this; +}; + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('/upload') + * .attach('content', new Blob(['hey!'], { type: "text/html"})) + * .end(callback); + * ``` + * + * @param {String} field + * @param {Blob|File} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + this._getFormData().append(field, file, filename || file.name); + return this; +}; + +Request.prototype._getFormData = function(){ + if (!this._formData) { + this._formData = new root.FormData(); + } + return this._formData; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + var fn = this._callback; + this.clearTimeout(); + fn(err, res); +}; + +/** + * Invoke callback with x-domain error. + * + * @api private + */ + +Request.prototype.crossDomainError = function(){ + var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.'); + err.crossDomain = true; + + err.status = this.status; + err.method = this.method; + err.url = this.url; + + this.callback(err); +}; + +/** + * Invoke callback with timeout error. + * + * @api private + */ + +Request.prototype._timeoutError = function(){ + var timeout = this._timeout; + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + this.callback(err); +}; + +/** + * Compose querystring to append to req.url + * + * @api private + */ + +Request.prototype._appendQueryString = function(){ + var query = this._query.join('&'); + if (query) { + this.url += ~this.url.indexOf('?') + ? '&' + query + : '?' + query; + } +}; + +/** + * Initiate request, invoking callback `fn(res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype.end = function(fn){ + var self = this; + var xhr = this.xhr = request.getXHR(); + var timeout = this._timeout; + var data = this._formData || this._data; + + // store callback + this._callback = fn || noop; + + // state change + xhr.onreadystatechange = function(){ + if (4 != xhr.readyState) return; + + // In IE9, reads to any property (e.g. status) off of an aborted XHR will + // result in the error "Could not complete the operation due to error c00c023f" + var status; + try { status = xhr.status } catch(e) { status = 0; } + + if (0 == status) { + if (self.timedout) return self._timeoutError(); + if (self._aborted) return; + return self.crossDomainError(); + } + self.emit('end'); + }; + + // progress + var handleProgress = function(e){ + if (e.total > 0) { + e.percent = e.loaded / e.total * 100; + } + e.direction = 'download'; + self.emit('progress', e); + }; + if (this.hasListeners('progress')) { + xhr.onprogress = handleProgress; + } + try { + if (xhr.upload && this.hasListeners('progress')) { + xhr.upload.onprogress = handleProgress; + } + } catch(e) { + // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist. + // Reported here: + // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context + } + + // timeout + if (timeout && !this._timer) { + this._timer = setTimeout(function(){ + self.timedout = true; + self.abort(); + }, timeout); + } + + // querystring + this._appendQueryString(); + + // initiate request + if (this.username && this.password) { + xhr.open(this.method, this.url, true, this.username, this.password); + } else { + xhr.open(this.method, this.url, true); + } + + // CORS + if (this._withCredentials) xhr.withCredentials = true; + + // body + if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) { + // serialize stuff + var contentType = this._header['content-type']; + var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : '']; + if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json']; + if (serialize) data = serialize(data); + } + + // set header fields + for (var field in this.header) { + if (null == this.header[field]) continue; + xhr.setRequestHeader(field, this.header[field]); + } + + if (this._responseType) { + xhr.responseType = this._responseType; + } + + // send stuff + this.emit('request', this); + + // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing) + // We need null here if data is undefined + xhr.send(typeof data !== 'undefined' ? data : null); + return this; +}; + + +/** + * Expose `Request`. + */ + +request.Request = Request; + +/** + * GET `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.get = function(url, data, fn){ + var req = request('GET', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.query(data); + if (fn) req.end(fn); + return req; +}; + +/** + * HEAD `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.head = function(url, data, fn){ + var req = request('HEAD', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * OPTIONS query to `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.options = function(url, data, fn){ + var req = request('OPTIONS', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * DELETE `url` with optional callback `fn(res)`. + * + * @param {String} url + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +function del(url, fn){ + var req = request('DELETE', url); + if (fn) req.end(fn); + return req; +}; + +request['del'] = del; +request['delete'] = del; + +/** + * PATCH `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.patch = function(url, data, fn){ + var req = request('PATCH', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * POST `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed} [data] + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.post = function(url, data, fn){ + var req = request('POST', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; + +/** + * PUT `url` with optional `data` and callback `fn(res)`. + * + * @param {String} url + * @param {Mixed|Function} [data] or fn + * @param {Function} [fn] + * @return {Request} + * @api public + */ + +request.put = function(url, data, fn){ + var req = request('PUT', url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + if (fn) req.end(fn); + return req; +}; diff --git a/node_modules/chai-http/node_modules/superagent/lib/is-object.js b/node_modules/chai-http/node_modules/superagent/lib/is-object.js new file mode 100644 index 0000000..dff357c --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/is-object.js @@ -0,0 +1,13 @@ +/** + * Check if `obj` is an object. + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +function isObject(obj) { + return null !== obj && 'object' === typeof obj; +} + +module.exports = isObject; diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/agent.js b/node_modules/chai-http/node_modules/superagent/lib/node/agent.js new file mode 100644 index 0000000..60f3cea --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/agent.js @@ -0,0 +1,82 @@ + +/** + * Module dependencies. + */ + +var CookieJar = require('cookiejar').CookieJar; +var CookieAccess = require('cookiejar').CookieAccessInfo; +var parse = require('url').parse; +var request = require('./index'); +var methods = require('methods'); + +/** + * Expose `Agent`. + */ + +module.exports = Agent; + +/** + * Initialize a new `Agent`. + * + * @api public + */ + +function Agent(options) { + if (!(this instanceof Agent)) return new Agent(options); + if (options) this._ca = options.ca; + this.jar = new CookieJar; +} + +/** + * Save the cookies in the given `res` to + * the agent's cookie jar for persistence. + * + * @param {Response} res + * @api private + */ + +Agent.prototype._saveCookies = function(res){ + var cookies = res.headers['set-cookie']; + if (cookies) this.jar.setCookies(cookies); +}; + +/** + * Attach cookies when available to the given `req`. + * + * @param {Request} req + * @api private + */ + +Agent.prototype._attachCookies = function(req){ + var url = parse(req.url); + var access = CookieAccess(url.hostname, url.pathname, 'https:' == url.protocol); + var cookies = this.jar.getCookies(access).toValueString(); + req.cookies = cookies; +}; + +// generate HTTP verb methods +if (methods.indexOf('del') == -1) { + // create a copy so we don't cause conflicts with + // other packages using the methods package and + // npm 3.x + methods = methods.slice(0); + methods.push('del'); +} +methods.forEach(function(method){ + var name = method; + method = 'del' == method ? 'delete' : method; + + method = method.toUpperCase(); + Agent.prototype[name] = function(url, fn){ + var req = request(method, url); + req.ca(this._ca); + + req.on('response', this._saveCookies.bind(this)); + req.on('redirect', this._saveCookies.bind(this)); + req.on('redirect', this._attachCookies.bind(this, req)); + this._attachCookies(req); + + fn && req.end(fn); + return req; + }; +}); diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/index.js b/node_modules/chai-http/node_modules/superagent/lib/node/index.js new file mode 100644 index 0000000..1fe2e95 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/index.js @@ -0,0 +1,952 @@ + +/** + * Module dependencies. + */ + +var debug = require('debug')('superagent'); +var formidable = require('formidable'); +var FormData = require('form-data'); +var Response = require('./response'); +var parse = require('url').parse; +var format = require('url').format; +var resolve = require('url').resolve; +var methods = require('methods'); +var Stream = require('stream'); +var utils = require('./utils'); +var extend = require('extend'); +var Part = require('./part'); +var mime = require('mime'); +var https = require('https'); +var http = require('http'); +var fs = require('fs'); +var qs = require('qs'); +var zlib = require('zlib'); +var util = require('util'); +var pkg = require('../../package.json'); +var requestBase = require('../request-base'); +var isObject = require('../is-object'); + +/** + * Expose the request function. + */ + +var request = exports = module.exports = require('../request').bind(null, Request); + +/** + * Expose the agent function + */ + +exports.agent = require('./agent'); + +/** + * Expose `Part`. + */ + +exports.Part = Part; + +/** + * Noop. + */ + +function noop(){}; + +/** + * Expose `Response`. + */ + +exports.Response = Response; + +/** + * Define "form" mime type. + */ + +mime.define({ + 'application/x-www-form-urlencoded': ['form', 'urlencoded', 'form-data'] +}); + +/** + * Protocol map. + */ + +exports.protocols = { + 'http:': http, + 'https:': https +}; + +/** + * Default serialization map. + * + * superagent.serialize['application/xml'] = function(obj){ + * return 'generated xml here'; + * }; + * + */ + +exports.serialize = { + 'application/x-www-form-urlencoded': qs.stringify, + 'application/json': JSON.stringify +}; + +/** + * Default parsers. + * + * superagent.parse['application/xml'] = function(res, fn){ + * fn(null, res); + * }; + * + */ + +exports.parse = require('./parsers'); + +/** + * Initialize internal header tracking properties on a request instance. + * + * @param {Object} req the instance + * @api private + */ +function _initHeaders(req) { + var ua = 'node-superagent/' + pkg.version; + req._header = { // coerces header names to lowercase + 'user-agent': ua + }; + req.header = { // preserves header name case + 'User-Agent': ua + }; +} + +/** + * Initialize a new `Request` with the given `method` and `url`. + * + * @param {String} method + * @param {String|Object} url + * @api public + */ + +function Request(method, url) { + Stream.call(this); + var self = this; + if ('string' != typeof url) url = format(url); + this._agent = false; + this._formData = null; + this.method = method; + this.url = url; + _initHeaders(this); + this.writable = true; + this._redirects = 0; + this.redirects(method === 'HEAD' ? 0 : 5); + this.cookies = ''; + this.qs = {}; + this.qsRaw = []; + this._redirectList = []; + this._streamRequest = false; + this.on('end', this.clearTimeout.bind(this)); +} + +/** + * Inherit from `Stream` (which inherits from `EventEmitter`). + * Mixin `requestBase`. + */ +util.inherits(Request, Stream); +for (var key in requestBase) { + Request.prototype[key] = requestBase[key]; +} + +/** + * Queue the given `file` as an attachment to the specified `field`, + * with optional `filename`. + * + * ``` js + * request.post('http://localhost/upload') + * .attach(new Buffer('Hello world'), 'hello.html') + * .end(callback); + * ``` + * + * A filename may also be used: + * + * ``` js + * request.post('http://localhost/upload') + * .attach('files', 'image.jpg') + * .end(callback); + * ``` + * + * @param {String} field + * @param {String|fs.ReadStream|Buffer} file + * @param {String} filename + * @return {Request} for chaining + * @api public + */ + +Request.prototype.attach = function(field, file, filename){ + if ('string' == typeof file) { + if (!filename) filename = file; + debug('creating `fs.ReadStream` instance for file: %s', file); + file = fs.createReadStream(file); + } else if (!filename && file.path) { + filename = file.path; + } + this._getFormData().append(field, file, { filename: filename }); + return this; +}; + +Request.prototype._getFormData = function() { + if (!this._formData) { + this._formData = new FormData(); + this._formData.on('error', function(err) { + this.emit('error', err); + this.abort(); + }.bind(this)); + } + return this._formData; +}; + +/** + * Return a new `Part` for this request. + * + * @return {Part} + * @api public + * @deprecated pass a readable stream in to `Request#attach()` instead + */ + +Request.prototype.part = util.deprecate(function(){ + return new Part(this); +}, '`Request#part()` is deprecated. ' + + 'Pass a readable stream in to `Request#attach()` instead.'); + +/** + * Gets/sets the `Agent` to use for this HTTP request. The default (if this + * function is not called) is to opt out of connection pooling (`agent: false`). + * + * @param {http.Agent} agent + * @return {http.Agent} + * @api public + */ + +Request.prototype.agent = function(agent){ + if (!arguments.length) return this._agent; + this._agent = agent; + return this; +}; + +/** + * Set _Content-Type_ response header passed through `mime.lookup()`. + * + * Examples: + * + * request.post('/') + * .type('xml') + * .send(xmlstring) + * .end(callback); + * + * request.post('/') + * .type('json') + * .send(jsonstring) + * .end(callback); + * + * request.post('/') + * .type('application/json') + * .send(jsonstring) + * .end(callback); + * + * @param {String} type + * @return {Request} for chaining + * @api public + */ + +Request.prototype.type = function(type){ + return this.set('Content-Type', ~type.indexOf('/') + ? type + : mime.lookup(type)); +}; + +/** + * Set _Accept_ response header passed through `mime.lookup()`. + * + * Examples: + * + * superagent.types.json = 'application/json'; + * + * request.get('/agent') + * .accept('json') + * .end(callback); + * + * request.get('/agent') + * .accept('application/json') + * .end(callback); + * + * @param {String} accept + * @return {Request} for chaining + * @api public + */ + +Request.prototype.accept = function(type){ + return this.set('Accept', ~type.indexOf('/') + ? type + : mime.lookup(type)); +}; + +/** + * Add query-string `val`. + * + * Examples: + * + * request.get('/shoes') + * .query('size=10') + * .query({ color: 'blue' }) + * + * @param {Object|String} val + * @return {Request} for chaining + * @api public + */ + +Request.prototype.query = function(val){ + if ('string' == typeof val) { + this.qsRaw.push(val); + return this; + } + + extend(this.qs, val); + return this; +}; + +/** + * Write raw `data` / `encoding` to the socket. + * + * @param {Buffer|String} data + * @param {String} encoding + * @return {Boolean} + * @api public + */ + +Request.prototype.write = function(data, encoding){ + var req = this.request(); + if (!this._streamRequest) { + this._streamRequest = true; + try { + // ensure querystring is appended before headers are sent + this._appendQueryString(req); + } catch (e) { + return this.emit('error', e); + } + } + return req.write(data, encoding); +}; + +/** + * Pipe the request body to `stream`. + * + * @param {Stream} stream + * @param {Object} options + * @return {Stream} + * @api public + */ + +Request.prototype.pipe = function(stream, options){ + this.piped = true; // HACK... + this.buffer(false); + var self = this; + this.end().req.on('response', function(res){ + // redirect + var redirect = isRedirect(res.statusCode); + if (redirect && self._redirects++ != self._maxRedirects) { + return self._redirect(res).pipe(stream, options); + } + + self.res = res; + self._emitResponse(); + if (self._aborted) return; + + if (self._shouldUnzip(res)) { + res.pipe(zlib.createUnzip()).pipe(stream, options); + } else { + res.pipe(stream, options); + } + res.on('end', function(){ + self.emit('end'); + }); + }); + return stream; +}; + +/** + * Enable / disable buffering. + * + * @return {Boolean} [val] + * @return {Request} for chaining + * @api public + */ + +Request.prototype.buffer = function(val){ + this._buffer = (false !== val); + return this; +}; + +/** + * Redirect to `url + * + * @param {IncomingMessage} res + * @return {Request} for chaining + * @api private + */ + +Request.prototype._redirect = function(res){ + var url = res.headers.location; + if (!url) { + return this.callback(new Error('No location header for redirect'), res); + } + + debug('redirect %s -> %s', this.url, url); + + // location + url = resolve(this.url, url); + + // ensure the response is being consumed + // this is required for Node v0.10+ + res.resume(); + + var headers = this.req._headers; + + var shouldStripCookie = parse(url).host !== parse(this.url).host; + + // implementation of 302 following defacto standard + if (res.statusCode == 301 || res.statusCode == 302){ + // strip Content-* related fields + // in case of POST etc + headers = utils.cleanHeader(this.req._headers, shouldStripCookie); + + // force GET + this.method = 'HEAD' == this.method + ? 'HEAD' + : 'GET'; + + // clear data + this._data = null; + } + // 303 is always GET + if (res.statusCode == 303) { + // strip Content-* related fields + // in case of POST etc + headers = utils.cleanHeader(this.req._headers, shouldStripCookie); + + // force method + this.method = 'GET'; + + // clear data + this._data = null; + } + // 307 preserves method + // 308 preserves method + delete headers.host; + + delete this.req; + delete this._formData; + + // remove all add header except User-Agent + _initHeaders(this) + + // redirect + this.url = url; + this.qs = {}; + this.qsRaw = []; + this.set(headers); + this.emit('redirect', res); + this._redirectList.push(this.url); + this.end(this._callback); + return this; +}; + +/** + * Set Authorization field value with `user` and `pass`. + * + * Examples: + * + * .auth('tobi', 'learnboost') + * .auth('tobi:learnboost') + * .auth('tobi') + * + * @param {String} user + * @param {String} pass + * @return {Request} for chaining + * @api public + */ + +Request.prototype.auth = function(user, pass){ + if (1 === arguments.length) pass = ''; + if (!~user.indexOf(':')) user = user + ':'; + var str = new Buffer(user + pass).toString('base64'); + return this.set('Authorization', 'Basic ' + str); +}; + +/** + * Set the certificate authority option for https request. + * + * @param {Buffer | Array} cert + * @return {Request} for chaining + * @api public + */ + +Request.prototype.ca = function(cert){ + this._ca = cert; + return this; +}; + +/** + * Return an http[s] request. + * + * @return {OutgoingMessage} + * @api private + */ + +Request.prototype.request = function(){ + if (this.req) return this.req; + + var self = this; + var options = {}; + var data = this._data; + var url = this.url; + + // default to http:// + if (0 != url.indexOf('http')) url = 'http://' + url; + url = parse(url); + + // options + options.method = this.method; + options.port = url.port; + options.path = url.pathname; + options.host = url.hostname; + options.ca = this._ca; + options.agent = this._agent; + + // initiate request + var mod = exports.protocols[url.protocol]; + + // request + var req = this.req = mod.request(options); + if ('HEAD' != options.method) req.setHeader('Accept-Encoding', 'gzip, deflate'); + this.protocol = url.protocol; + this.host = url.host; + + // expose events + req.on('drain', function(){ self.emit('drain'); }); + + req.on('error', function(err){ + // flag abortion here for out timeouts + // because node will emit a faux-error "socket hang up" + // when request is aborted before a connection is made + if (self._aborted) return; + // if we've recieved a response then we don't want to let + // an error in the request blow up the response + if (self.response) return; + self.callback(err); + }); + + // auth + if (url.auth) { + var auth = url.auth.split(':'); + this.auth(auth[0], auth[1]); + } + + // query + if (url.search) + this.query(url.search.substr(1)); + + // add cookies + if (this.cookies) req.setHeader('Cookie', this.cookies); + + for (var key in this.header) { + req.setHeader(key, this.header[key]); + } + + return req; +}; + +/** + * Invoke the callback with `err` and `res` + * and handle arity check. + * + * @param {Error} err + * @param {Response} res + * @api private + */ + +Request.prototype.callback = function(err, res){ + // Avoid the error which is emitted from 'socket hang up' to cause the fn undefined error on JS runtime. + var fn = this._callback || noop; + this.clearTimeout(); + if (this.called) return console.warn('double callback!'); + this.called = true; + + if (err) { + err.response = res; + } + + // only emit error event if there is a listener + // otherwise we assume the callback to `.end()` will get the error + if (err && this.listeners('error').length > 0) this.emit('error', err); + + if (err) { + return fn(err, res); + } + + if (res && res.status >= 200 && res.status < 300) { + return fn(err, res); + } + + var msg = 'Unsuccessful HTTP response'; + if (res) { + msg = http.STATUS_CODES[res.status] || msg; + } + var new_err = new Error(msg); + new_err.original = err; + new_err.response = res; + new_err.status = (res) ? res.status : undefined; + + fn(err || new_err, res); +}; + +/** + * Compose querystring to append to req.path + * + * @return {String} querystring + * @api private + */ + +Request.prototype._appendQueryString = function(req){ + var querystring = qs.stringify(this.qs, { indices: false }); + querystring += ((querystring.length && this.qsRaw.length) ? '&' : '') + this.qsRaw.join('&'); + req.path += querystring.length + ? (~req.path.indexOf('?') ? '&' : '?') + querystring + : ''; +}; + +/** + * Initiate request, invoking callback `fn(err, res)` + * with an instanceof `Response`. + * + * @param {Function} fn + * @return {Request} for chaining + * @api public + */ + +Request.prototype._emitResponse = function(body, files){ + var response = new Response(this); + this.response = response; + response.redirects = this._redirectList; + if (undefined !== body) { + response.body = body; + } + response.files = files; + this.emit('response', response); + return response; +}; + +Request.prototype.end = function(fn){ + var self = this; + var data = this._data; + var req = this.request(); + var buffer = this._buffer; + var method = this.method; + var timeout = this._timeout; + debug('%s %s', this.method, this.url); + + // store callback + this._callback = fn || noop; + + // querystring + try { + this._appendQueryString(req); + } catch (e) { + return this.callback(e); + } + + // timeout + if (timeout && !this._timer) { + debug('timeout %sms %s %s', timeout, this.method, this.url); + this._timer = setTimeout(function(){ + var err = new Error('timeout of ' + timeout + 'ms exceeded'); + err.timeout = timeout; + err.code = 'ECONNABORTED'; + self.abort(); + self.callback(err); + }, timeout); + } + + // body + if ('HEAD' != method && !req._headerSent) { + // serialize stuff + if ('string' != typeof data) { + var contentType = req.getHeader('Content-Type') + // Parse out just the content type from the header (ignore the charset) + if (contentType) contentType = contentType.split(';')[0] + var serialize = exports.serialize[contentType]; + if (!serialize && isJSON(contentType)) serialize = exports.serialize['application/json']; + if (serialize) data = serialize(data); + } + + // content-length + if (data && !req.getHeader('Content-Length')) { + req.setHeader('Content-Length', Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data)); + } + } + + // response + req.on('response', function(res){ + debug('%s %s -> %s', self.method, self.url, res.statusCode); + + if (self.piped) { + return; + } + + var max = self._maxRedirects; + var mime = utils.type(res.headers['content-type'] || '') || 'text/plain'; + var type = mime.split('/')[0]; + var multipart = 'multipart' == type; + var redirect = isRedirect(res.statusCode); + var parser = self._parser; + + self.res = res; + + // redirect + if (redirect && self._redirects++ != max) { + return self._redirect(res); + } + + if ('HEAD' == self.method) { + self.emit('end'); + self.callback(null, self._emitResponse()); + return; + } + + // zlib support + if (self._shouldUnzip(res)) { + utils.unzip(req, res); + } + + if (!parser) { + if (multipart) { + var form = new formidable.IncomingForm(); + parser = form.parse.bind(form); + buffer = true; + } else if (isImage(mime)) { + parser = exports.parse.image; + buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent + } else if ('text' == type) { + parser = exports.parse.text; + buffer = (buffer !== false); + } else if (exports.parse[mime]) { + parser = exports.parse[mime]; + + // everyone wants their own white-labeled json + } else if (isJSON(mime)) { + parser = exports.parse['application/json']; + buffer = (buffer !== false); + } else if (buffer) { + parser = exports.parse.text; + } + } + + // by default only buffer text/*, json and messed up thing from hell + if (undefined === buffer && isText(mime) || isJSON(mime)) buffer = true; + + var parserHandlesEnd = false; + if (parser) { + try { + // Unbuffered parsers are supposed to emit response early, + // which is weird BTW, because response.body won't be there. + parserHandlesEnd = buffer; + + parser(res, function(err, obj, files) { + if (err && !self._aborted) { + return self.callback(err); + } + + res.body = obj; // Deprecated. For backwards compat only. It's not the response object user sees. + + if (parserHandlesEnd) { + self.emit('end'); + self.callback(null, self._emitResponse(obj, files)); + } + }); + } catch (err) { + self.callback(err); + return; + } + } + + self.res = res; + + // unbuffered + if (!buffer) { + debug('unbuffered %s %s', self.method, self.url); + self.callback(null, self._emitResponse()); + if (multipart) return // allow multipart to handle end event + res.on('end', function(){ + debug('end %s %s', self.method, self.url); + self.emit('end'); + }) + return; + } + + // terminating events + res.on('error', function(err){ + self.callback(err, null); + }); + if (!parserHandlesEnd) res.on('end', function(){ + debug('end %s %s', self.method, self.url); + // TODO: unless buffering emit earlier to stream + self.emit('end'); + self.callback(null, self._emitResponse()); + }); + }); + + this.emit('request', this); + + // if a FormData instance got created, then we send that as the request body + var formData = this._formData; + if (formData) { + + // set headers + var headers = formData.getHeaders(); + for (var i in headers) { + debug('setting FormData header: "%s: %s"', i, headers[i]); + req.setHeader(i, headers[i]); + } + + // attempt to get "Content-Length" header + formData.getLength(function(err, length) { + // TODO: Add chunked encoding when no length (if err) + + debug('got FormData Content-Length: %s', length); + if ('number' == typeof length) { + req.setHeader('Content-Length', length); + } + + var getProgressMonitor = function () { + var lengthComputable = true; + var total = req.getHeader('Content-Length'); + var loaded = 0; + + var progress = new Stream.Transform(); + progress._transform = function (chunk, encoding, cb) { + loaded += chunk.length; + self.emit('progress', { + direction: 'upload', + lengthComputable: lengthComputable, + loaded: loaded, + total: total + }); + cb(null, chunk); + }; + return progress; + }; + formData.pipe(getProgressMonitor()).pipe(req); + }); + } else { + req.end(data); + } + + return this; +}; + +/** + * Check whether response has a non-0-sized gzip-encoded body + */ +Request.prototype._shouldUnzip = function(res){ + if (res.statusCode === 204 || res.statusCode === 304) { + // These aren't supposed to have any body + return false; + } + + // header content is a string, and distinction between 0 and no information is crucial + if ('0' === res.headers['content-length']) { + // We know that the body is empty (unfortunately, this check does not cover chunked encoding) + return false; + } + + // console.log(res); + return /^\s*(?:deflate|gzip)\s*$/.test(res.headers['content-encoding']); +}; + +/** + * Expose `Request`. + */ + +exports.Request = Request; + +// generate HTTP verb methods +if (methods.indexOf('del') == -1) { + // create a copy so we don't cause conflicts with + // other packages using the methods package and + // npm 3.x + methods = methods.slice(0); + methods.push('del'); +} +methods.forEach(function(method){ + var name = method; + method = 'del' == method ? 'delete' : method; + + method = method.toUpperCase(); + request[name] = function(url, data, fn){ + var req = request(method, url); + if ('function' == typeof data) fn = data, data = null; + if (data) req.send(data); + fn && req.end(fn); + return req; + }; +}); + +/** + * Check if `mime` is text and should be buffered. + * + * @param {String} mime + * @return {Boolean} + * @api public + */ + +function isText(mime) { + var parts = mime.split('/'); + var type = parts[0]; + var subtype = parts[1]; + + return 'text' == type + || 'x-www-form-urlencoded' == subtype; +} + +/** + * Check if `mime` is image + * + * @param {String} mime + * @return {Boolean} + * @api public + */ + +function isImage(mime) { + var parts = mime.split('/'); + var type = parts[0]; + var subtype = parts[1]; + + return 'image' == type; +} + +/** + * Check if `mime` is json or has +json structured syntax suffix. + * + * @param {String} mime + * @return {Boolean} + * @api private + */ + +function isJSON(mime) { + return /[\/+]json\b/.test(mime); +} + +/** + * Check if we should follow the redirect `code`. + * + * @param {Number} code + * @return {Boolean} + * @api private + */ + +function isRedirect(code) { + return ~[301, 302, 303, 305, 307, 308].indexOf(code); +} diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/parsers/image.js b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/image.js new file mode 100644 index 0000000..b3e0ebc --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/image.js @@ -0,0 +1,10 @@ +module.exports = function(res, fn){ + var data = []; // Binary data needs binary storage + + res.on('data', function(chunk){ + data.push(chunk); + }); + res.on('end', function () { + fn(null, Buffer.concat(data)); + }); +}; \ No newline at end of file diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/parsers/index.js b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/index.js new file mode 100644 index 0000000..61a98cd --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/index.js @@ -0,0 +1,5 @@ + +exports['application/x-www-form-urlencoded'] = require('./urlencoded'); +exports['application/json'] = require('./json'); +exports.text = require('./text'); +exports.image = require('./image'); diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/parsers/json.js b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/json.js new file mode 100644 index 0000000..b71662d --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/json.js @@ -0,0 +1,19 @@ + +module.exports = function parseJSON(res, fn){ + res.text = ''; + res.setEncoding('utf8'); + res.on('data', function(chunk){ res.text += chunk;}); + res.on('end', function(){ + try { + var body = res.text && JSON.parse(res.text); + } catch (e) { + var err = e; + // issue #675: return the raw response if the response parsing fails + err.rawResponse = res.text || null; + // issue #876: return the http status code if the response parsing fails + err.statusCode = res.statusCode; + } finally { + fn(err, body); + } + }); +}; diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/parsers/text.js b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/text.js new file mode 100644 index 0000000..03575c6 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/text.js @@ -0,0 +1,7 @@ + +module.exports = function(res, fn){ + res.text = ''; + res.setEncoding('utf8'); + res.on('data', function(chunk){ res.text += chunk; }); + res.on('end', fn); +}; \ No newline at end of file diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/parsers/urlencoded.js b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/urlencoded.js new file mode 100644 index 0000000..245c665 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/parsers/urlencoded.js @@ -0,0 +1,19 @@ + +/** + * Module dependencies. + */ + +var qs = require('qs'); + +module.exports = function(res, fn){ + res.text = ''; + res.setEncoding('ascii'); + res.on('data', function(chunk){ res.text += chunk; }); + res.on('end', function(){ + try { + fn(null, qs.parse(res.text)); + } catch (err) { + fn(err); + } + }); +}; \ No newline at end of file diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/part.js b/node_modules/chai-http/node_modules/superagent/lib/node/part.js new file mode 100644 index 0000000..d7123bb --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/part.js @@ -0,0 +1,149 @@ + +/** + * Module dependencies. + */ + +var util = require('util'); +var mime = require('mime'); +var FormData = require('form-data'); +var PassThrough = require('readable-stream/passthrough'); + +/** + * Initialize a new `Part` for the given `req`. + * + * @param {Request} req + * @api public + * @deprecated pass a readable stream in to `Request#attach()` instead + */ + +var Part = function (req) { + PassThrough.call(this); + this._req = req; + this._attached = false; + this._name = null; + this._type = null; + this._header = null; + this._filename = null; + + this.once('pipe', this._attach.bind(this)); +}; +Part = util.deprecate(Part, 'The `Part()` constructor is deprecated. ' + + 'Pass a readable stream in to `Request#attach()` instead.'); + +/** + * Inherit from `PassThrough`. + */ + +util.inherits(Part, PassThrough); + +/** + * Expose `Part`. + */ + +module.exports = Part; + +/** + * Set header `field` to `val`. + * + * @param {String} field + * @param {String} val + * @return {Part} for chaining + * @api public + */ + +Part.prototype.set = function(field, val){ + //if (!this._header) this._header = {}; + //this._header[field] = val; + //return this; + throw new TypeError('setting custom form-data part headers is unsupported'); +}; + +/** + * Set _Content-Type_ response header passed through `mime.lookup()`. + * + * Examples: + * + * res.type('html'); + * res.type('.html'); + * + * @param {String} type + * @return {Part} for chaining + * @api public + */ + +Part.prototype.type = function(type){ + var lookup = mime.lookup(type); + this._type = lookup; + //this.set('Content-Type', lookup); + return this; +}; + +/** + * Set the "name" portion for the _Content-Disposition_ header field. + * + * @param {String} name + * @return {Part} for chaining + * @api public + */ + +Part.prototype.name = function(name){ + this._name = name; + return this; +}; + +/** + * Set _Content-Disposition_ header field to _attachment_ with `filename` + * and field `name`. + * + * @param {String} name + * @param {String} filename + * @return {Part} for chaining + * @api public + */ + +Part.prototype.attachment = function(name, filename){ + this.name(name); + if (filename) { + this.type(filename); + this._filename = filename; + } + return this; +}; + +/** + * Calls `FormData#append()` on the Request instance's FormData object. + * + * Gets called implicitly upon the first `write()` call, or the "pipe" event. + * + * @api private + */ + +Part.prototype._attach = function(){ + if (this._attached) return; + this._attached = true; + + if (!this._name) throw new Error('must call `Part#name()` first!'); + + // add `this` Stream's readable side as a stream for this Part + this._req._getFormData().append(this._name, this, { + contentType: this._type, + filename: this._filename + }); + + // restore PassThrough's default `write()` function now that we're setup + this.write = PassThrough.prototype.write; +}; + +/** + * Write `data` with `encoding`. + * + * @param {Buffer|String} data + * @param {String} encoding + * @return {Boolean} + * @api public + */ + +Part.prototype.write = function(){ + this._attach(); + return this.write.apply(this, arguments); +}; diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/response.js b/node_modules/chai-http/node_modules/superagent/lib/node/response.js new file mode 100644 index 0000000..489a075 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/response.js @@ -0,0 +1,215 @@ + +/** + * Module dependencies. + */ + +var util = require('util'); +var utils = require('./utils'); +var Stream = require('stream'); + +/** + * Expose `Response`. + */ + +module.exports = Response; + +/** + * Initialize a new `Response` with the given `xhr`. + * + * - set flags (.ok, .error, etc) + * - parse header + * + * @param {Request} req + * @param {Object} options + * @constructor + * @extends {Stream} + * @implements {ReadableStream} + * @api private + */ + +function Response(req, options) { + Stream.call(this); + options = options || {}; + var res = this.res = req.res; + this.request = req; + this.req = req.req; + this.links = {}; + this.text = res.text; + this.body = res.body !== undefined ? res.body : {}; + this.files = res.files || {}; + this.buffered = 'string' == typeof this.text; + this.header = this.headers = res.headers; + this._setStatusProperties(res.statusCode); + this._setHeaderProperties(this.header); + this.setEncoding = res.setEncoding.bind(res); + res.on('data', this.emit.bind(this, 'data')); + res.on('end', this.emit.bind(this, 'end')); + res.on('close', this.emit.bind(this, 'close')); + res.on('error', this.emit.bind(this, 'error')); +} + +/** + * Inherit from `Stream`. + */ + +util.inherits(Response, Stream); + +/** + * Get case-insensitive `field` value. + * + * @param {String} field + * @return {String} + * @api public + */ + +Response.prototype.get = function(field){ + return this.header[field.toLowerCase()]; +}; + +/** + * Implements methods of a `ReadableStream` + */ + +Response.prototype.destroy = function(err){ + this.res.destroy(err); +}; + +/** + * Pause. + */ + +Response.prototype.pause = function(){ + this.res.pause(); +}; + +/** + * Resume. + */ + +Response.prototype.resume = function(){ + this.res.resume(); +}; + +/** + * Return an `Error` representative of this response. + * + * @return {Error} + * @api public + */ + +Response.prototype.toError = function(){ + var req = this.req; + var method = req.method; + var path = req.path; + + var msg = 'cannot ' + method + ' ' + path + ' (' + this.status + ')'; + var err = new Error(msg); + err.status = this.status; + err.text = this.text; + err.method = method; + err.path = path; + + return err; +}; + +/** + * Set header related properties: + * + * - `.type` the content type without params + * + * A response of "Content-Type: text/plain; charset=utf-8" + * will provide you with a `.type` of "text/plain". + * + * @param {Object} header + * @api private + */ + +Response.prototype._setHeaderProperties = function(header){ + // TODO: moar! + // TODO: make this a util + + // content-type + var ct = this.header['content-type'] || ''; + + // params + var params = utils.params(ct); + for (var key in params) this[key] = params[key]; + + this.type = utils.type(ct); + + // links + try { + if (header.link) this.links = utils.parseLinks(header.link); + } catch (err) { + // ignore + } +}; + +/** + * Set flags such as `.ok` based on `status`. + * + * For example a 2xx response will give you a `.ok` of __true__ + * whereas 5xx will be __false__ and `.error` will be __true__. The + * `.clientError` and `.serverError` are also available to be more + * specific, and `.statusType` is the class of error ranging from 1..5 + * sometimes useful for mapping respond colors etc. + * + * "sugar" properties are also defined for common cases. Currently providing: + * + * - .noContent + * - .badRequest + * - .unauthorized + * - .notAcceptable + * - .notFound + * + * @param {Number} status + * @api private + */ + +Response.prototype._setStatusProperties = function(status){ + var type = status / 100 | 0; + + // status / class + this.status = this.statusCode = status; + this.statusType = type; + + // basics + this.info = 1 == type; + this.ok = 2 == type; + this.redirect = 3 == type; + this.clientError = 4 == type; + this.serverError = 5 == type; + this.error = (4 == type || 5 == type) + ? this.toError() + : false; + + // sugar + this.accepted = 202 == status; + this.noContent = 204 == status; + this.badRequest = 400 == status; + this.unauthorized = 401 == status; + this.notAcceptable = 406 == status; + this.forbidden = 403 == status; + this.notFound = 404 == status; +}; + +Response.prototype.setStatusProperties = function(status){ + console.warn("In superagent 2.x setStatusProperties is a private method"); + return this._setStatusProperties(status); +}; + +/** + * To json. + * + * @return {Object} + * @api public + */ + +Response.prototype.toJSON = function(){ + return { + req: this.request.toJSON(), + header: this.header, + status: this.status, + text: this.text + }; +}; diff --git a/node_modules/chai-http/node_modules/superagent/lib/node/utils.js b/node_modules/chai-http/node_modules/superagent/lib/node/utils.js new file mode 100644 index 0000000..822929e --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/node/utils.js @@ -0,0 +1,142 @@ + +/** + * Module dependencies. + */ + +var StringDecoder = require('string_decoder').StringDecoder; +var Stream = require('stream'); +var zlib; + +/** + * Require zlib module for Node 0.6+ + */ + +try { + zlib = require('zlib'); +} catch (e) { } + +/** + * Return the mime type for the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.type = function(str){ + return str.split(/ *; */).shift(); +}; + +/** + * Return header field parameters. + * + * @param {String} str + * @return {Object} + * @api private + */ + +exports.params = function(str){ + return str.split(/ *; */).reduce(function(obj, str){ + var parts = str.split(/ *= */); + var key = parts.shift(); + var val = parts.shift(); + + if (key && val) obj[key] = val; + return obj; + }, {}); +}; + +/** + * Parse Link header fields. + * + * @param {String} str + * @return {Object} + * @api private + */ + +exports.parseLinks = function(str){ + return str.split(/ *, */).reduce(function(obj, str){ + var parts = str.split(/ *; */); + var url = parts[0].slice(1, -1); + var rel = parts[1].split(/ *= */)[1].slice(1, -1); + obj[rel] = url; + return obj; + }, {}); +}; + +/** + * Buffers response data events and re-emits when they're unzipped. + * + * @param {Request} req + * @param {Response} res + * @api private + */ + +exports.unzip = function(req, res){ + if (!zlib) return; + + var unzip = zlib.createUnzip(); + var stream = new Stream; + var decoder; + + // make node responseOnEnd() happy + stream.req = req; + + unzip.on('error', function(err){ + stream.emit('error', err); + }); + + // pipe to unzip + res.pipe(unzip); + + // override `setEncoding` to capture encoding + res.setEncoding = function(type){ + decoder = new StringDecoder(type); + }; + + // decode upon decompressing with captured encoding + unzip.on('data', function(buf){ + if (decoder) { + var str = decoder.write(buf); + if (str.length) stream.emit('data', str); + } else { + stream.emit('data', buf); + } + }); + + unzip.on('end', function(){ + stream.emit('end'); + }); + + // override `on` to capture data listeners + var _on = res.on; + res.on = function(type, fn){ + if ('data' == type || 'end' == type) { + stream.on(type, fn); + } else if ('error' == type) { + stream.on(type, fn); + _on.call(res, type, fn); + } else { + _on.call(res, type, fn); + } + }; +}; + +/** + * Strip content related fields from `header`. + * + * @param {Object} header + * @return {Object} header + * @api private + */ + +exports.cleanHeader = function(header, shouldStripCookie){ + delete header['content-type']; + delete header['content-length']; + delete header['transfer-encoding']; + delete header['host']; + if (shouldStripCookie) { + delete header['cookie']; + } + return header; +}; diff --git a/node_modules/chai-http/node_modules/superagent/lib/request-base.js b/node_modules/chai-http/node_modules/superagent/lib/request-base.js new file mode 100644 index 0000000..d082528 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/request-base.js @@ -0,0 +1,347 @@ +/** + * Module of mixed-in functions shared between node and client code + */ +var isObject = require('./is-object'); + +/** + * Clear previous timeout. + * + * @return {Request} for chaining + * @api public + */ + +exports.clearTimeout = function _clearTimeout(){ + this._timeout = 0; + clearTimeout(this._timer); + return this; +}; + +/** + * Override default response body parser + * + * This function will be called to convert incoming data into request.body + * + * @param {Function} + * @api public + */ + +exports.parse = function parse(fn){ + this._parser = fn; + return this; +}; + +/** + * Override default request body serializer + * + * This function will be called to convert data set via .send or .attach into payload to send + * + * @param {Function} + * @api public + */ + +exports.serialize = function serialize(fn){ + this._serializer = fn; + return this; +}; + +/** + * Set timeout to `ms`. + * + * @param {Number} ms + * @return {Request} for chaining + * @api public + */ + +exports.timeout = function timeout(ms){ + this._timeout = ms; + return this; +}; + +/** + * Promise support + * + * @param {Function} resolve + * @param {Function} reject + * @return {Request} + */ + +exports.then = function then(resolve, reject) { + if (!this._fullfilledPromise) { + var self = this; + this._fullfilledPromise = new Promise(function(innerResolve, innerReject){ + self.end(function(err, res){ + if (err) innerReject(err); else innerResolve(res); + }); + }); + } + return this._fullfilledPromise.then(resolve, reject); +} + +/** + * Allow for extension + */ + +exports.use = function use(fn) { + fn(this); + return this; +} + + +/** + * Get request header `field`. + * Case-insensitive. + * + * @param {String} field + * @return {String} + * @api public + */ + +exports.get = function(field){ + return this._header[field.toLowerCase()]; +}; + +/** + * Get case-insensitive header `field` value. + * This is a deprecated internal API. Use `.get(field)` instead. + * + * (getHeader is no longer used internally by the superagent code base) + * + * @param {String} field + * @return {String} + * @api private + * @deprecated + */ + +exports.getHeader = exports.get; + +/** + * Set header `field` to `val`, or multiple fields with one object. + * Case-insensitive. + * + * Examples: + * + * req.get('/') + * .set('Accept', 'application/json') + * .set('X-API-Key', 'foobar') + * .end(callback); + * + * req.get('/') + * .set({ Accept: 'application/json', 'X-API-Key': 'foobar' }) + * .end(callback); + * + * @param {String|Object} field + * @param {String} val + * @return {Request} for chaining + * @api public + */ + +exports.set = function(field, val){ + if (isObject(field)) { + for (var key in field) { + this.set(key, field[key]); + } + return this; + } + this._header[field.toLowerCase()] = val; + this.header[field] = val; + return this; +}; + +/** + * Remove header `field`. + * Case-insensitive. + * + * Example: + * + * req.get('/') + * .unset('User-Agent') + * .end(callback); + * + * @param {String} field + */ +exports.unset = function(field){ + delete this._header[field.toLowerCase()]; + delete this.header[field]; + return this; +}; + +/** + * Write the field `name` and `val` for "multipart/form-data" + * request bodies. + * + * ``` js + * request.post('/upload') + * .field('foo', 'bar') + * .end(callback); + * ``` + * + * @param {String} name + * @param {String|Blob|File|Buffer|fs.ReadStream} val + * @return {Request} for chaining + * @api public + */ +exports.field = function(name, val) { + this._getFormData().append(name, val); + return this; +}; + +/** + * Abort the request, and clear potential timeout. + * + * @return {Request} + * @api public + */ +exports.abort = function(){ + if (this._aborted) { + return this; + } + this._aborted = true; + this.xhr && this.xhr.abort(); // browser + this.req && this.req.abort(); // node + this.clearTimeout(); + this.emit('abort'); + return this; +}; + +/** + * Enable transmission of cookies with x-domain requests. + * + * Note that for this to work the origin must not be + * using "Access-Control-Allow-Origin" with a wildcard, + * and also must set "Access-Control-Allow-Credentials" + * to "true". + * + * @api public + */ + +exports.withCredentials = function(){ + // This is browser-only functionality. Node side is no-op. + this._withCredentials = true; + return this; +}; + +/** + * Set the max redirects to `n`. Does noting in browser XHR implementation. + * + * @param {Number} n + * @return {Request} for chaining + * @api public + */ + +exports.redirects = function(n){ + this._maxRedirects = n; + return this; +}; + +/** + * Convert to a plain javascript object (not JSON string) of scalar properties. + * Note as this method is designed to return a useful non-this value, + * it cannot be chained. + * + * @return {Object} describing method, url, and data of this request + * @api public + */ + +exports.toJSON = function(){ + return { + method: this.method, + url: this.url, + data: this._data, + headers: this._header + }; +}; + +/** + * Check if `obj` is a host object, + * we don't want to serialize these :) + * + * TODO: future proof, move to compoent land + * + * @param {Object} obj + * @return {Boolean} + * @api private + */ + +exports._isHost = function _isHost(obj) { + var str = {}.toString.call(obj); + + switch (str) { + case '[object File]': + case '[object Blob]': + case '[object FormData]': + return true; + default: + return false; + } +} + +/** + * Send `data` as the request body, defaulting the `.type()` to "json" when + * an object is given. + * + * Examples: + * + * // manual json + * request.post('/user') + * .type('json') + * .send('{"name":"tj"}') + * .end(callback) + * + * // auto json + * request.post('/user') + * .send({ name: 'tj' }) + * .end(callback) + * + * // manual x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send('name=tj') + * .end(callback) + * + * // auto x-www-form-urlencoded + * request.post('/user') + * .type('form') + * .send({ name: 'tj' }) + * .end(callback) + * + * // defaults to x-www-form-urlencoded + * request.post('/user') + * .send('name=tobi') + * .send('species=ferret') + * .end(callback) + * + * @param {String|Object} data + * @return {Request} for chaining + * @api public + */ + +exports.send = function(data){ + var obj = isObject(data); + var type = this._header['content-type']; + + // merge + if (obj && isObject(this._data)) { + for (var key in data) { + this._data[key] = data[key]; + } + } else if ('string' == typeof data) { + // default to x-www-form-urlencoded + if (!type) this.type('form'); + type = this._header['content-type']; + if ('application/x-www-form-urlencoded' == type) { + this._data = this._data + ? this._data + '&' + data + : data; + } else { + this._data = (this._data || '') + data; + } + } else { + this._data = data; + } + + if (!obj || this._isHost(data)) return this; + + // default to json + if (!type) this.type('json'); + return this; +}; diff --git a/node_modules/chai-http/node_modules/superagent/lib/request.js b/node_modules/chai-http/node_modules/superagent/lib/request.js new file mode 100644 index 0000000..53a3e6a --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/lib/request.js @@ -0,0 +1,32 @@ +// The node and browser modules expose versions of this with the +// appropriate constructor function bound as first argument +/** + * Issue a request: + * + * Examples: + * + * request('GET', '/users').end(callback) + * request('/users').end(callback) + * request('/users', callback) + * + * @param {String} method + * @param {String|Function} url or callback + * @return {Request} + * @api public + */ + +function request(RequestConstructor, method, url) { + // callback + if ('function' == typeof url) { + return new RequestConstructor('GET', method).end(url); + } + + // url first + if (2 == arguments.length) { + return new RequestConstructor('GET', method); + } + + return new RequestConstructor(method, url); +} + +module.exports = request; diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/History.md b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/History.md new file mode 100644 index 0000000..9189c60 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/History.md @@ -0,0 +1,68 @@ + +1.2.1 / 2016-04-18 +================== + + * enable client side use + +1.2.0 / 2014-02-12 +================== + + * prefix events with `$` to support object prototype method names + +1.1.3 / 2014-06-20 +================== + + * republish for npm + * add LICENSE file + +1.1.2 / 2014-02-10 +================== + + * package: rename to "component-emitter" + * package: update "main" and "component" fields + * Add license to Readme (same format as the other components) + * created .npmignore + * travis stuff + +1.1.1 / 2013-12-01 +================== + + * fix .once adding .on to the listener + * docs: Emitter#off() + * component: add `.repo` prop + +1.1.0 / 2013-10-20 +================== + + * add `.addEventListener()` and `.removeEventListener()` aliases + +1.0.1 / 2013-06-27 +================== + + * add support for legacy ie + +1.0.0 / 2013-02-26 +================== + + * add `.off()` support for removing all listeners + +0.0.6 / 2012-10-08 +================== + + * add `this._callbacks` initialization to prevent funky gotcha + +0.0.5 / 2012-09-07 +================== + + * fix `Emitter.call(this)` usage + +0.0.3 / 2012-07-11 +================== + + * add `.listeners()` + * rename `.has()` to `.hasListeners()` + +0.0.2 / 2012-06-28 +================== + + * fix `.off()` with `.once()`-registered callbacks diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/LICENSE b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/LICENSE new file mode 100644 index 0000000..d6e43f2 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/LICENSE @@ -0,0 +1,24 @@ +(The MIT License) + +Copyright (c) 2014 Component 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. diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/Readme.md b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/Readme.md new file mode 100644 index 0000000..0466411 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/Readme.md @@ -0,0 +1,74 @@ +# Emitter [![Build Status](https://travis-ci.org/component/emitter.png)](https://travis-ci.org/component/emitter) + + Event emitter component. + +## Installation + +``` +$ component install component/emitter +``` + +## API + +### Emitter(obj) + + The `Emitter` may also be used as a mixin. For example + a "plain" object may become an emitter, or you may + extend an existing prototype. + + As an `Emitter` instance: + +```js +var Emitter = require('emitter'); +var emitter = new Emitter; +emitter.emit('something'); +``` + + As a mixin: + +```js +var Emitter = require('emitter'); +var user = { name: 'tobi' }; +Emitter(user); + +user.emit('im a user'); +``` + + As a prototype mixin: + +```js +var Emitter = require('emitter'); +Emitter(User.prototype); +``` + +### Emitter#on(event, fn) + + Register an `event` handler `fn`. + +### Emitter#once(event, fn) + + Register a single-shot `event` handler `fn`, + removed immediately after it is invoked the + first time. + +### Emitter#off(event, fn) + + * Pass `event` and `fn` to remove a listener. + * Pass `event` to remove all listeners on that event. + * Pass nothing to remove all listeners on all events. + +### Emitter#emit(event, ...) + + Emit an `event` with variable option args. + +### Emitter#listeners(event) + + Return an array of callbacks, or an empty array. + +### Emitter#hasListeners(event) + + Check if this emitter has `event` handlers. + +## License + +MIT diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/index.js b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/index.js new file mode 100644 index 0000000..df94c78 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/index.js @@ -0,0 +1,163 @@ + +/** + * Expose `Emitter`. + */ + +if (typeof module !== 'undefined') { + module.exports = Emitter; +} + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks['$' + event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/package.json b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/package.json new file mode 100644 index 0000000..e1ad368 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/component-emitter/package.json @@ -0,0 +1,182 @@ +{ + "name": "component-emitter", + "description": "Event emitter", + "version": "1.2.1", + "license": "MIT", + "devDependencies": { + "mocha": "*", + "should": "*" + }, + "component": { + "scripts": { + "emitter/index.js": "index.js" + } + }, + "main": "index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/component/emitter.git" + }, + "scripts": { + "test": "make test" + }, + "files": [ + "index.js", + "LICENSE" + ], + "gitHead": "187492ab8028c7221b589bdfd482b715149cd868", + "bugs": { + "url": "https://github.com/component/emitter/issues" + }, + "homepage": "https://github.com/component/emitter#readme", + "_id": "component-emitter@1.2.1", + "_shasum": "137918d6d78283f7df7a6b7c5a63e140e69425e6", + "_from": "component-emitter@>=1.2.0 <2.0.0", + "_npmVersion": "2.10.1", + "_nodeVersion": "0.12.4", + "_npmUser": { + "name": "nami-doc", + "email": "karp@hotmail.fr" + }, + "maintainers": [ + { + "name": "tootallnate", + "email": "nathan@tootallnate.net" + }, + { + "name": "hughsk", + "email": "hughskennedy@gmail.com" + }, + { + "name": "trevorgerhardt", + "email": "trevorgerhardt@gmail.com" + }, + { + "name": "timaschew", + "email": "timaschew@gmail.com" + }, + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "rauchg", + "email": "rauchg@gmail.com" + }, + { + "name": "retrofox", + "email": "rdsuarez@gmail.com" + }, + { + "name": "coreh", + "email": "thecoreh@gmail.com" + }, + { + "name": "forbeslindesay", + "email": "forbes@lindesay.co.uk" + }, + { + "name": "kelonye", + "email": "kelonyemitchel@gmail.com" + }, + { + "name": "mattmueller", + "email": "mattmuelle@gmail.com" + }, + { + "name": "yields", + "email": "yields@icloud.com" + }, + { + "name": "anthonyshort", + "email": "antshort@gmail.com" + }, + { + "name": "jongleberry", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "ianstormtaylor", + "email": "ian@ianstormtaylor.com" + }, + { + "name": "cristiandouce", + "email": "cristian@gravityonmars.com" + }, + { + "name": "swatinem", + "email": "arpad.borsos@googlemail.com" + }, + { + "name": "stagas", + "email": "gstagas@gmail.com" + }, + { + "name": "amasad", + "email": "amjad.masad@gmail.com" + }, + { + "name": "juliangruber", + "email": "julian@juliangruber.com" + }, + { + "name": "calvinfo", + "email": "calvin@calv.info" + }, + { + "name": "dominicbarnes", + "email": "dominic@dbarnes.info" + }, + { + "name": "blakeembrey", + "email": "hello@blakeembrey.com" + }, + { + "name": "timoxley", + "email": "secoif@gmail.com" + }, + { + "name": "jonathanong", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "queckezz", + "email": "fabian.eichenberger@gmail.com" + }, + { + "name": "nami-doc", + "email": "vendethiel@hotmail.fr" + }, + { + "name": "clintwood", + "email": "clint@anotherway.co.za" + }, + { + "name": "thehydroimpulse", + "email": "dnfagnan@gmail.com" + }, + { + "name": "stephenmathieson", + "email": "me@stephenmathieson.com" + }, + { + "name": "dfcreative", + "email": "df.creative@gmail.com" + }, + { + "name": "defunctzombie", + "email": "shtylman@gmail.com" + } + ], + "dist": { + "shasum": "137918d6d78283f7df7a6b7c5a63e140e69425e6", + "tarball": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz" + }, + "_npmOperationalInternal": { + "host": "packages-12-west.internal.npmjs.com", + "tmp": "tmp/component-emitter-1.2.1.tgz_1461005707641_0.14232611074112356" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/.eslintrc b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.eslintrc new file mode 100644 index 0000000..d49f173 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.eslintrc @@ -0,0 +1,192 @@ +{ + "env": { + "browser": false, + "node": true, + "amd": false, + "mocha": false, + "jasmine": false + }, + + "rules": { + "accessor-pairs": [2, { getWithoutSet: false, setWithoutGet: true }], + "array-bracket-spacing": [2, "never", { + "singleValue": false, + "objectsInArrays": false, + "arraysInArrays": false + }], + "block-scoped-var": [0], + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "camelcase": [2], + "comma-dangle": [2, "never"], + "comma-spacing": [2], + "comma-style": [2, "last"], + "complexity": [2, 15], + "computed-property-spacing": [2, "never"], + "consistent-return": [2], + "consistent-this": [0, "that"], + "constructor-super": [2], + "curly": [2, "all"], + "default-case": [2], + "dot-notation": [2, { "allowKeywords": true }], + "eol-last": [2], + "eqeqeq": [2], + "func-names": [0], + "func-style": [2, "expression"], + "generator-star-spacing": [2, { "before": false, "after": true }], + "global-strict": [0, "never"], + "guard-for-in": [0], + "handle-callback-err": [0], + "key-spacing": [2, { "beforeColon": false, "afterColon": true }], + "linebreak-style": [2, "unix"], + "lines-around-comment": [2, { + "beforeBlockComment": false, + "afterBlockComment": false, + "beforeLineComment": false, + "beforeLineComment": false, + "allowBlockStart": true, + "allowBlockEnd": true + }], + "quotes": [2, "single", "avoid-escape"], + "max-depth": [1, 4], + "max-len": [0, 80, 4], + "max-nested-callbacks": [2, 2], + "max-params": [2, 2], + "max-statements": [2, 21], + "new-parens": [2], + "new-cap": [2], + "newline-after-var": [0], + "no-alert": [2], + "no-array-constructor": [2], + "no-bitwise": [0], + "no-caller": [2], + "no-catch-shadow": [2], + "no-cond-assign": [2], + "no-console": [2], + "no-constant-condition": [2], + "no-continue": [2], + "no-control-regex": [2], + "no-debugger": [2], + "no-delete-var": [2], + "no-div-regex": [0], + "no-dupe-args": [2], + "no-dupe-keys": [2], + "no-duplicate-case": [2], + "no-else-return": [0], + "no-empty": [2], + "no-empty-character-class": [2], + "no-empty-label": [2], + "no-eq-null": [0], + "no-eval": [2], + "no-ex-assign": [2], + "no-extend-native": [2], + "no-extra-bind": [2], + "no-extra-boolean-cast": [2], + "no-extra-parens": [0], + "no-extra-semi": [2], + "no-fallthrough": [2], + "no-floating-decimal": [2], + "no-func-assign": [2], + "no-implied-eval": [2], + "no-inline-comments": [0], + "no-inner-declarations": [2, "functions"], + "no-invalid-regexp": [2], + "no-irregular-whitespace": [2], + "no-iterator": [2], + "no-label-var": [2], + "no-labels": [2], + "no-lone-blocks": [2], + "no-lonely-if": [2], + "no-loop-func": [2], + "no-mixed-requires": [0, false], + "no-mixed-spaces-and-tabs": [2, false], + "no-multi-spaces": [2], + "no-multi-str": [2], + "no-multiple-empty-lines": [2, {"max": 1}], + "no-native-reassign": [2], + "no-negated-in-lhs": [2], + "no-nested-ternary": [0], + "no-new": [2], + "no-new-func": [2], + "no-new-object": [2], + "no-new-require": [0], + "no-new-wrappers": [2], + "no-obj-calls": [2], + "no-octal": [2], + "no-octal-escape": [2], + "no-param-reassign": [2], + "no-path-concat": [0], + "no-plusplus": [0], + "no-process-env": [0], + "no-process-exit": [2], + "no-proto": [2], + "no-redeclare": [2], + "no-regex-spaces": [2], + "no-reserved-keys": [2], + "no-restricted-modules": [0], + "no-return-assign": [2, "always"], + "no-script-url": [2], + "no-self-compare": [0], + "no-sequences": [2], + "no-shadow": [2], + "no-shadow-restricted-names": [2], + "no-space-before-semi": [2], + "no-spaced-func": [2], + "no-sparse-arrays": [2], + "no-sync": [0], + "no-ternary": [0], + "no-this-before-super": [2], + "no-throw-literal": [2], + "no-trailing-spaces": [2, { "skipBlankLines": false }], + "no-undef": [2], + "no-undef-init": [2], + "no-undefined": [0], + "no-underscore-dangle": [2], + "no-unexpected-multiline": [2], + "no-unneeded-ternary": [2], + "no-unreachable": [2], + "no-unused-expressions": [2], + "no-unused-vars": [2, { "vars": "all", "args": "after-used" }], + "no-use-before-define": [2], + "no-void": [0], + "no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }], + "no-with": [2], + "no-wrap-func": [2], + "object-curly-spacing": [2, "always"], + "object-shorthand": [2, "never"], + "one-var": [0], + "operator-assignment": [0, "always"], + "operator-linebreak": [2, "none"], + "padded-blocks": [0], + "prefer-const": [0], + "quote-props": [0], + "radix": [0], + "semi": [2], + "semi-spacing": [2, { "before": false, "after": true }], + "sort-vars": [0], + "space-after-keywords": [2, "always"], + "space-before-function-paren": [2, { "anonymous": "always", "named": "never" }], + "space-before-blocks": [0, "always"], + "space-in-brackets": [0, "never", { + "singleValue": true, + "arraysInArrays": false, + "arraysInObjects": false, + "objectsInArrays": true, + "objectsInObjects": true, + "propertyName": false + }], + "space-in-parens": [2, "never"], + "space-infix-ops": [2], + "space-return-throw-case": [2], + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "spaced-comment": [2, "always"], + "spaced-line-comment": [0, "always"], + "strict": [2, "global"], + "use-isnan": [2], + "valid-jsdoc": [0], + "valid-typeof": [2], + "vars-on-top": [0], + "wrap-iife": [2], + "wrap-regex": [2], + "yoda": [2, "never", { "exceptRange": true, "onlyEquality": false }] + } +} diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/.jscs.json b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.jscs.json new file mode 100644 index 0000000..7e84b28 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.jscs.json @@ -0,0 +1,104 @@ +{ + "additionalRules": [], + + "requireSemicolons": true, + + "disallowMultipleSpaces": true, + + "disallowIdentifierNames": [], + + "requireCurlyBraces": ["if", "else", "for", "while", "do", "try", "catch"], + + "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], + + "disallowSpaceAfterKeywords": [], + + "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true }, + "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, + "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, + "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, + "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, + + "requireSpaceBetweenArguments": true, + + "disallowSpacesInsideParentheses": true, + + "disallowSpacesInsideArrayBrackets": true, + + "disallowQuotedKeysInObjects": "allButReserved", + + "disallowSpaceAfterObjectKeys": true, + + "requireCommaBeforeLineBreak": true, + + "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], + "requireSpaceAfterPrefixUnaryOperators": [], + + "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], + "requireSpaceBeforePostfixUnaryOperators": [], + + "disallowSpaceBeforeBinaryOperators": [], + "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], + + "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], + "disallowSpaceAfterBinaryOperators": [], + + "disallowImplicitTypeConversion": ["binary", "string"], + + "disallowKeywords": ["with", "eval"], + + "requireKeywordsOnNewLine": [], + "disallowKeywordsOnNewLine": ["else"], + + "requireLineFeedAtFileEnd": true, + + "disallowTrailingWhitespace": true, + + "disallowTrailingComma": true, + + "excludeFiles": ["node_modules/**", "vendor/**"], + + "disallowMultipleLineStrings": true, + + "requireDotNotation": true, + + "requireParenthesesAroundIIFE": true, + + "validateLineBreaks": "LF", + + "validateQuoteMarks": { + "escape": true, + "mark": "'" + }, + + "disallowOperatorBeforeLineBreak": [], + + "requireSpaceBeforeKeywords": [ + "do", + "for", + "if", + "else", + "switch", + "case", + "try", + "catch", + "finally", + "while", + "with", + "return" + ], + + "validateAlignedFunctionParameters": { + "lineBreakAfterOpeningBraces": true, + "lineBreakBeforeClosingBraces": true + }, + + "requirePaddingNewLinesBeforeExport": true, + + "validateNewlineAfterArrayElements": { + "maximum": 6 + }, + + "requirePaddingNewLinesAfterUseStrict": true +} + diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/.npmignore b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.npmignore new file mode 100644 index 0000000..30d74d2 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.npmignore @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/.travis.yml b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.travis.yml new file mode 100644 index 0000000..ebef644 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/.travis.yml @@ -0,0 +1,44 @@ +language: node_js +node_js: + - "iojs-v2.3" + - "iojs-v2.2" + - "iojs-v2.1" + - "iojs-v2.0" + - "iojs-v1.8" + - "iojs-v1.7" + - "iojs-v1.6" + - "iojs-v1.5" + - "iojs-v1.4" + - "iojs-v1.3" + - "iojs-v1.2" + - "iojs-v1.1" + - "iojs-v1.0" + - "0.12" + - "0.11" + - "0.10" + - "0.9" + - "0.8" + - "0.6" + - "0.4" +before_install: + - '[ "${TRAVIS_NODE_VERSION}" = "0.6" ] || npm install -g npm@1.4.28 && npm install -g npm' +sudo: false +matrix: + fast_finish: true + allow_failures: + - node_js: "iojs-v2.2" + - node_js: "iojs-v2.1" + - node_js: "iojs-v2.0" + - node_js: "iojs-v1.7" + - node_js: "iojs-v1.6" + - node_js: "iojs-v1.5" + - node_js: "iojs-v1.4" + - node_js: "iojs-v1.3" + - node_js: "iojs-v1.2" + - node_js: "iojs-v1.1" + - node_js: "iojs-v1.0" + - node_js: "0.11" + - node_js: "0.9" + - node_js: "0.8" + - node_js: "0.6" + - node_js: "0.4" diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/CHANGELOG.md b/node_modules/chai-http/node_modules/superagent/node_modules/extend/CHANGELOG.md new file mode 100644 index 0000000..ee0cfd6 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/CHANGELOG.md @@ -0,0 +1,69 @@ +3.0.0 / 2015-07-01 +================== + * [Possible breaking change] Use global "strict" directive (#32) + * [Tests] `int` is an ES3 reserved word + * [Tests] Test up to `io.js` `v2.3` + * [Tests] Add `npm run eslint` + * [Dev Deps] Update `covert`, `jscs` + +2.0.1 / 2015-04-25 +================== + * Use an inline `isArray` check, for ES3 browsers. (#27) + * Some old browsers fail when an identifier is `toString` + * Test latest `node` and `io.js` versions on `travis-ci`; speed up builds + * Add license info to package.json (#25) + * Update `tape`, `jscs` + * Adding a CHANGELOG + +2.0.0 / 2014-10-01 +================== + * Increase code coverage to 100%; run code coverage as part of tests + * Add `npm run lint`; Run linter as part of tests + * Remove nodeType and setInterval checks in isPlainObject + * Updating `tape`, `jscs`, `covert` + * General style and README cleanup + +1.3.0 / 2014-06-20 +================== + * Add component.json for browser support (#18) + * Use SVG for badges in README (#16) + * Updating `tape`, `covert` + * Updating travis-ci to work with multiple node versions + * Fix `deep === false` bug (returning target as {}) (#14) + * Fixing constructor checks in isPlainObject + * Adding additional test coverage + * Adding `npm run coverage` + * Add LICENSE (#13) + * Adding a warning about `false`, per #11 + * General style and whitespace cleanup + +1.2.1 / 2013-09-14 +================== + * Fixing hasOwnProperty bugs that would only have shown up in specific browsers. Fixes #8 + * Updating `tape` + +1.2.0 / 2013-09-02 +================== + * Updating the README: add badges + * Adding a missing variable reference. + * Using `tape` instead of `buster` for tests; add more tests (#7) + * Adding node 0.10 to Travis CI (#6) + * Enabling "npm test" and cleaning up package.json (#5) + * Add Travis CI. + +1.1.3 / 2012-12-06 +================== + * Added unit tests. + * Ensure extend function is named. (Looks nicer in a stack trace.) + * README cleanup. + +1.1.1 / 2012-11-07 +================== + * README cleanup. + * Added installation instructions. + * Added a missing semicolon + +1.0.0 / 2012-04-08 +================== + * Initial commit + diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/LICENSE b/node_modules/chai-http/node_modules/superagent/node_modules/extend/LICENSE new file mode 100644 index 0000000..e16d6a5 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright (c) 2014 Stefan Thomas + +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. + diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/README.md b/node_modules/chai-http/node_modules/superagent/node_modules/extend/README.md new file mode 100644 index 0000000..632fb0f --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/README.md @@ -0,0 +1,62 @@ +[![Build Status][travis-svg]][travis-url] +[![dependency status][deps-svg]][deps-url] +[![dev dependency status][dev-deps-svg]][dev-deps-url] + +# extend() for Node.js [![Version Badge][npm-version-png]][npm-url] + +`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true. + +## Installation + +This package is available on [npm][npm-url] as: `extend` + +``` sh +npm install extend +``` + +## Usage + +**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)** + +*Extend one object with one or more others, returning the modified object.* + +Keep in mind that the target object will be modified, and will be returned from extend(). + +If a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s). +Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. +Warning: passing `false` as the first argument is not supported. + +### Arguments + +* `deep` *Boolean* (optional) +If set, the merge becomes recursive (i.e. deep copy). +* `target` *Object* +The object to extend. +* `object1` *Object* +The object that will be merged into the first. +* `objectN` *Object* (Optional) +More objects to merge into the first. + +## License + +`node-extend` is licensed under the [MIT License][mit-license-url]. + +## Acknowledgements + +All credit to the jQuery authors for perfecting this amazing utility. + +Ported to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jonathan Buchanan][github-insin] and [Jordan Harband][github-ljharb]. + +[travis-svg]: https://travis-ci.org/justmoon/node-extend.svg +[travis-url]: https://travis-ci.org/justmoon/node-extend +[npm-url]: https://npmjs.org/package/extend +[mit-license-url]: http://opensource.org/licenses/MIT +[github-justmoon]: https://github.com/justmoon +[github-insin]: https://github.com/insin +[github-ljharb]: https://github.com/ljharb +[npm-version-png]: http://vb.teelaun.ch/justmoon/node-extend.svg +[deps-svg]: https://david-dm.org/justmoon/node-extend.svg +[deps-url]: https://david-dm.org/justmoon/node-extend +[dev-deps-svg]: https://david-dm.org/justmoon/node-extend/dev-status.svg +[dev-deps-url]: https://david-dm.org/justmoon/node-extend#info=devDependencies + diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/component.json b/node_modules/chai-http/node_modules/superagent/node_modules/extend/component.json new file mode 100644 index 0000000..1500a2f --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/component.json @@ -0,0 +1,32 @@ +{ + "name": "extend", + "author": "Stefan Thomas (http://www.justmoon.net)", + "version": "3.0.0", + "description": "Port of jQuery.extend for node.js and the browser.", + "scripts": [ + "index.js" + ], + "contributors": [ + { + "name": "Jordan Harband", + "url": "https://github.com/ljharb" + } + ], + "keywords": [ + "extend", + "clone", + "merge" + ], + "repository" : { + "type": "git", + "url": "https://github.com/justmoon/node-extend.git" + }, + "dependencies": { + }, + "devDependencies": { + "tape" : "~3.0.0", + "covert": "~0.4.0", + "jscs": "~1.6.2" + } +} + diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/index.js b/node_modules/chai-http/node_modules/superagent/node_modules/extend/index.js new file mode 100644 index 0000000..f5ec75d --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/index.js @@ -0,0 +1,86 @@ +'use strict'; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) {/**/} + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +module.exports = function extend() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0], + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + target[name] = copy; + } + } + } + } + } + + // Return the modified object + return target; +}; + diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/extend/package.json b/node_modules/chai-http/node_modules/superagent/node_modules/extend/package.json new file mode 100644 index 0000000..7b86254 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/extend/package.json @@ -0,0 +1,73 @@ +{ + "name": "extend", + "author": { + "name": "Stefan Thomas", + "email": "justmoon@members.fsf.org", + "url": "http://www.justmoon.net" + }, + "version": "3.0.0", + "description": "Port of jQuery.extend for node.js and the browser", + "main": "index", + "scripts": { + "test": "npm run lint && node test/index.js && npm run coverage-quiet", + "coverage": "covert test/index.js", + "coverage-quiet": "covert test/index.js --quiet", + "lint": "npm run jscs && npm run eslint", + "jscs": "jscs *.js */*.js", + "eslint": "eslint *.js */*.js" + }, + "contributors": [ + { + "name": "Jordan Harband", + "url": "https://github.com/ljharb" + } + ], + "keywords": [ + "extend", + "clone", + "merge" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/justmoon/node-extend.git" + }, + "dependencies": {}, + "devDependencies": { + "tape": "^4.0.0", + "covert": "^1.1.0", + "jscs": "^1.13.1", + "eslint": "^0.24.0" + }, + "license": "MIT", + "gitHead": "148e7270cab2e9413af2cd0cab147070d755ed6d", + "bugs": { + "url": "https://github.com/justmoon/node-extend/issues" + }, + "homepage": "https://github.com/justmoon/node-extend#readme", + "_id": "extend@3.0.0", + "_shasum": "5a474353b9f3353ddd8176dfd37b91c83a46f1d4", + "_from": "extend@>=3.0.0 <4.0.0", + "_npmVersion": "2.11.3", + "_nodeVersion": "2.3.1", + "_npmUser": { + "name": "ljharb", + "email": "ljharb@gmail.com" + }, + "dist": { + "shasum": "5a474353b9f3353ddd8176dfd37b91c83a46f1d4", + "tarball": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz" + }, + "maintainers": [ + { + "name": "justmoon", + "email": "justmoon@members.fsf.org" + }, + { + "name": "ljharb", + "email": "ljharb@gmail.com" + } + ], + "directories": {}, + "_resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.dockerignore b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.dockerignore new file mode 100644 index 0000000..c67305c --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.dockerignore @@ -0,0 +1,7 @@ +*.iml +*.sublime-* +*.un~ +.idea +sftp-config.json +node_modules/ +test/tmp/ diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.editorconfig b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.editorconfig new file mode 100644 index 0000000..0f09989 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.editorconfig @@ -0,0 +1,10 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintignore b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintignore new file mode 100644 index 0000000..8d87b1d --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintignore @@ -0,0 +1 @@ +node_modules/* diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintrc b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintrc new file mode 100644 index 0000000..129fcef --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/.eslintrc @@ -0,0 +1,64 @@ +{ + "env": { + "node": true, + "browser": false + }, + "rules": { + // 2-space indentation + "indent": [2, 2, {"SwitchCase": 1}], + // Require strings to use single quotes + "quotes": [2, "single"], + // Allow only unix line-endings + "linebreak-style": [2, "unix"], + // Always require semicolons + "semi": [2, "always"], + // Require curly braces for multi-line control statements + "curly": [2, "multi-line"], + // Always handle callback error cases + "handle-callback-err": [2, "^err"], + // Require JSDoc for all function definitions + "valid-jsdoc": [2, { + "requireReturn": false, + "requireReturnDescription": false, + "prefer": { + "return": "returns" + } + }], + "require-jsdoc": [2, { + "require": { + "FunctionDeclaration": true + } + }], + "no-redeclare": [2, { "builtinGlobals": true }], + "no-shadow": [2, { "builtinGlobals": true, "hoist": "all" }], + // Disallow using variables before they've been defined + // functions are ok + "no-use-before-define": [2, "nofunc"], + "no-shadow-restricted-names": 2, + "no-extra-semi": 2, + // Disallow unused variables + "no-unused-vars": 2, + "no-undef": 2, + // Use if () { } + // ^ space + "keyword-spacing": 2, + // Use if () { } + // ^ space + "space-before-blocks": [2, "always"], + // eslint can't handle this, so the check is disabled. + "key-spacing": 0, + "strict": 0, + // Do not force dot-notation + "dot-notation": 0, + "eol-last": 0, + "no-new": 0, + "semi-spacing": 0, + // Allow multi spaces around operators since they are + // used for alignment. This is not consistent in the + // code. + "no-multi-spaces": 0, + "eqeqeq": 0, + "no-mixed-requires": 0, + "no-console": 0 + } +} diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/License b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/License new file mode 100644 index 0000000..c7ff12a --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/License @@ -0,0 +1,19 @@ +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and 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. diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/README.md b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/README.md new file mode 100644 index 0000000..e857db6 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/README.md @@ -0,0 +1,218 @@ +# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data) + +A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications. + +The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd]. + +[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface +[streams2-thing]: http://nodejs.org/api/stream.html#stream_compatibility_with_older_node_versions + +[![Linux Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=linux:0.10-5.x)](https://travis-ci.org/form-data/form-data) +[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/form-data/master.svg?label=windows:0.10-5.x)](https://ci.appveyor.com/project/alexindigo/form-data) +[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/master.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master) + +[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data) +[![Codacy Badge](https://img.shields.io/codacy/43ece80331c246179695e41f81eeffe2.svg)](https://www.codacy.com/app/form-data/form-data) +[![bitHound Overall Score](https://www.bithound.io/github/form-data/form-data/badges/score.svg)](https://www.bithound.io/github/form-data/form-data) + +## Install + +``` +npm install form-data +``` + +## Usage + +In this example we are constructing a form with 3 fields that contain a string, +a buffer and a file stream. + +``` javascript +var FormData = require('form-data'); +var fs = require('fs'); + +var form = new FormData(); +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_file', fs.createReadStream('/foo/bar.jpg')); +``` + +Also you can use http-response stream: + +``` javascript +var FormData = require('form-data'); +var http = require('http'); + +var form = new FormData(); + +http.request('http://nodejs.org/images/logo.png', function(response) { + form.append('my_field', 'my value'); + form.append('my_buffer', new Buffer(10)); + form.append('my_logo', response); +}); +``` + +Or @mikeal's [request](https://github.com/request/request) stream: + +``` javascript +var FormData = require('form-data'); +var request = require('request'); + +var form = new FormData(); + +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_logo', request('http://nodejs.org/images/logo.png')); +``` + +In order to submit this form to a web application, call ```submit(url, [callback])``` method: + +``` javascript +form.submit('http://example.org/', function(err, res) { + // res – response object (http.IncomingMessage) // + res.resume(); +}); + +``` + +For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods. + +### Alternative submission methods + +You can use node's http client interface: + +``` javascript +var http = require('http'); + +var request = http.request({ + method: 'post', + host: 'example.org', + path: '/upload', + headers: form.getHeaders() +}); + +form.pipe(request); + +request.on('response', function(res) { + console.log(res.statusCode); +}); +``` + +Or if you would prefer the `'Content-Length'` header to be set for you: + +``` javascript +form.submit('example.org/upload', function(err, res) { + console.log(res.statusCode); +}); +``` + +To use custom headers and pre-known length in parts: + +``` javascript +var CRLF = '\r\n'; +var form = new FormData(); + +var options = { + header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, + knownLength: 1 +}; + +form.append('my_buffer', buffer, options); + +form.submit('http://example.com/', function(err, res) { + if (err) throw err; + console.log('Done'); +}); +``` + +Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually: + +``` javascript +someModule.stream(function(err, stdout, stderr) { + if (err) throw err; + + var form = new FormData(); + + form.append('file', stdout, { + filename: 'unicycle.jpg', + contentType: 'image/jpg', + knownLength: 19806 + }); + + form.submit('http://example.com/', function(err, res) { + if (err) throw err; + console.log('Done'); + }); +}); +``` + +For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter: + +``` javascript +form.submit({ + host: 'example.com', + path: '/probably.php?extra=params', + auth: 'username:password' +}, function(err, res) { + console.log(res.statusCode); +}); +``` + +In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`: + +``` javascript +form.submit({ + host: 'example.com', + path: '/surelynot.php', + headers: {'x-test-header': 'test-header-value'} +}, function(err, res) { + console.log(res.statusCode); +}); +``` + +### Integration with other libraries + +#### Request + +Form submission using [request](https://github.com/request/request): + +```javascript +var formData = { + my_field: 'my_value', + my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), +}; + +request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) { + if (err) { + return console.error('upload failed:', err); + } + console.log('Upload successful! Server responded with:', body); +}); +``` + +For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads). + +#### node-fetch + +You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch): + +```javascript +var form = new FormData(); + +form.append('a', 1); + +fetch('http://example.com', { method: 'POST', body: form }) + .then(function(res) { + return res.json(); + }).then(function(json) { + console.log(json); + }); +``` + +## Notes + +- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround. +- If it feels like FormData hangs after submit and you're on ```node-0.10```, please check [Compatibility with Older Node Versions][streams2-thing] + +## License + +Form-Data is licensed under the MIT license. diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/browser.js b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/browser.js new file mode 100644 index 0000000..8141d65 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/browser.js @@ -0,0 +1,2 @@ +/* eslint-env browser */ +module.exports = FormData; diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/form_data.js b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/form_data.js new file mode 100644 index 0000000..55328b4 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/form_data.js @@ -0,0 +1,411 @@ +var CombinedStream = require('combined-stream'); +var util = require('util'); +var path = require('path'); +var http = require('http'); +var https = require('https'); +var parseUrl = require('url').parse; +var fs = require('fs'); +var mime = require('mime-types'); +var async = require('async'); +var populate = require('./populate.js'); + +// Public API +module.exports = FormData; + +// make it a Stream +util.inherits(FormData, CombinedStream); + +/** + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. + * + * @constructor + */ +function FormData() { + if (!(this instanceof FormData)) { + throw new TypeError('Failed to construct FormData: Please use the _new_ operator, this object constructor cannot be called as a function.'); + } + + this._overheadLength = 0; + this._valueLength = 0; + this._lengthRetrievers = []; + + CombinedStream.call(this); +} + +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + +FormData.prototype.append = function(field, value, options) { + + options = options || {}; + + // allow filename as single option + if (typeof options == 'string') { + options = {filename: options}; + } + + var append = CombinedStream.prototype.append.bind(this); + + // all that streamy business can't handle numbers + if (typeof value == 'number') { + value = '' + value; + } + + // https://github.com/felixge/node-form-data/issues/38 + if (util.isArray(value)) { + // Please convert your array into string + // the way web server expects it + this._error(new Error('Arrays are not supported.')); + return; + } + + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); + + append(header); + append(value); + append(footer); + + // pass along options.knownLength + this._trackLength(header, value, options); +}; + +FormData.prototype._trackLength = function(header, value, options) { + var valueLength = 0; + + // used w/ getLengthSync(), when length is known. + // e.g. for streaming directly from a remote server, + // w/ a known file a size, and not wanting to wait for + // incoming file to finish to get its size. + if (options.knownLength != null) { + valueLength += +options.knownLength; + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === 'string') { + valueLength = Buffer.byteLength(value); + } + + this._valueLength += valueLength; + + // @check why add CRLF? does this account for custom/multiple CRLFs? + this._overheadLength += + Buffer.byteLength(header) + + FormData.LINE_BREAK.length; + + // empty or either doesn't have path or not an http response + if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) { + return; + } + + // no need to bother with the length + if (!options.knownLength) { + this._lengthRetrievers.push(function(next) { + + if (value.hasOwnProperty('fd')) { + + // take read range into a account + // `end` = Infinity –> read file till the end + // + // TODO: Looks like there is bug in Node fs.createReadStream + // it doesn't respect `end` options without `start` options + // Fix it when node fixes it. + // https://github.com/joyent/node/issues/7819 + if (value.end != undefined && value.end != Infinity && value.start != undefined) { + + // when end specified + // no need to calculate range + // inclusive, starts with 0 + next(null, value.end + 1 - (value.start ? value.start : 0)); + + // not that fast snoopy + } else { + // still need to fetch file size from fs + fs.stat(value.path, function(err, stat) { + + var fileSize; + + if (err) { + next(err); + return; + } + + // update final size based on the range options + fileSize = stat.size - (value.start ? value.start : 0); + next(null, fileSize); + }); + } + + // or http response + } else if (value.hasOwnProperty('httpVersion')) { + next(null, +value.headers['content-length']); + + // or request stream http://github.com/mikeal/request + } else if (value.hasOwnProperty('httpModule')) { + // wait till response come back + value.on('response', function(response) { + value.pause(); + next(null, +response.headers['content-length']); + }); + value.resume(); + + // something else + } else { + next('Unknown stream'); + } + }); + } +}; + +FormData.prototype._multiPartHeader = function(field, value, options) { + // custom header specified (as string)? + // it becomes responsible for boundary + // (e.g. to handle extra CRLFs on .NET servers) + if (options.header) { + return options.header; + } + + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); + + var contents = ''; + var headers = { + // add custom disposition as third element or keep it two elements if not + 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + 'Content-Type': [].concat(contentType || []) + }; + + for (var prop in headers) { + if (headers[prop].length) { + contents += prop + ': ' + headers[prop].join('; ') + FormData.LINE_BREAK; + } + } + + return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; +}; + +FormData.prototype._getContentDisposition = function(value, options) { + + var contentDisposition; + + // custom filename takes precedence + // fs- and request- streams have path property + var filename = options.filename || value.path; + + // or try http response + if (!filename && value.readable && value.hasOwnProperty('httpVersion')) { + filename = value.client._httpMessage.path; + } + + if (filename) { + contentDisposition = 'filename="' + path.basename(filename) + '"'; + } + + return contentDisposition; +}; + +FormData.prototype._getContentType = function(value, options) { + + // use custom content-type above all + var contentType = options.contentType; + + // or try `path` from fs-, request- streams + if (!contentType && value.path) { + contentType = mime.lookup(value.path); + } + + // or if it's http-reponse + if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) { + contentType = value.headers['content-type']; + } + + // or guess it from the filename + if (!contentType && options.filename) { + contentType = mime.lookup(options.filename); + } + + // fallback to the default content type if `value` is not simple value + if (!contentType && typeof value == 'object') { + contentType = FormData.DEFAULT_CONTENT_TYPE; + } + + return contentType; +}; + +FormData.prototype._multiPartFooter = function() { + return function(next) { + var footer = FormData.LINE_BREAK; + + var lastPart = (this._streams.length === 0); + if (lastPart) { + footer += this._lastBoundary(); + } + + next(footer); + }.bind(this); +}; + +FormData.prototype._lastBoundary = function() { + return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; + +FormData.prototype.getHeaders = function(userHeaders) { + var header; + var formHeaders = { + 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() + }; + + for (header in userHeaders) { + if (userHeaders.hasOwnProperty(header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; + } + } + + return formHeaders; +}; + +FormData.prototype.getCustomHeaders = function(contentType) { + contentType = contentType ? contentType : 'multipart/form-data'; + + var formHeaders = { + 'content-type': contentType + '; boundary=' + this.getBoundary(), + 'content-length': this.getLengthSync() + }; + + return formHeaders; +}; + +FormData.prototype.getBoundary = function() { + if (!this._boundary) { + this._generateBoundary(); + } + + return this._boundary; +}; + +FormData.prototype._generateBoundary = function() { + // This generates a 50 character boundary similar to those used by Firefox. + // They are optimized for boyer-moore parsing. + var boundary = '--------------------------'; + for (var i = 0; i < 24; i++) { + boundary += Math.floor(Math.random() * 10).toString(16); + } + + this._boundary = boundary; +}; + +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually +// and add it as knownLength option +FormData.prototype.getLengthSync = function() { + var knownLength = this._overheadLength + this._valueLength; + + // Don't get confused, there are 3 "internal" streams for each keyval pair + // so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + // https://github.com/form-data/form-data/issues/40 + if (this._lengthRetrievers.length) { + // Some async length retrievers are present + // therefore synchronous length calculation is false. + // Please use getLength(callback) to get proper length + this._error(new Error('Cannot calculate proper length in synchronous way.')); + } + + return knownLength; +}; + +FormData.prototype.getLength = function(cb) { + var knownLength = this._overheadLength + this._valueLength; + + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + if (!this._lengthRetrievers.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; + } + + async.parallel(this._lengthRetrievers, function(err, values) { + if (err) { + cb(err); + return; + } + + values.forEach(function(length) { + knownLength += length; + }); + + cb(null, knownLength); + }); +}; + +FormData.prototype.submit = function(params, cb) { + var request + , options + , defaults = {method: 'post'} + ; + + // parse provided url if it's string + // or treat it as options object + if (typeof params == 'string') { + + params = parseUrl(params); + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname + }, defaults); + + // use custom params + } else { + + options = populate(params, defaults); + // if no port provided use default one + if (!options.port) { + options.port = options.protocol == 'https:' ? 443 : 80; + } + } + + // put that good code in getHeaders to some use + options.headers = this.getHeaders(params.headers); + + // https if specified, fallback to http in any other case + if (options.protocol == 'https:') { + request = https.request(options); + } else { + request = http.request(options); + } + + // get content length and fire away + this.getLength(function(err, length) { + if (err) { + this._error(err); + return; + } + + // add content length + request.setHeader('Content-Length', length); + + this.pipe(request); + if (cb) { + request.on('error', cb); + request.on('response', cb.bind(this, null)); + } + }.bind(this)); + + return request; +}; + +FormData.prototype._error = function(err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit('error', err); + } +}; diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/populate.js b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/populate.js new file mode 100644 index 0000000..6f64a6d --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/lib/populate.js @@ -0,0 +1,9 @@ +// populates missing values +module.exports = function(dst, src) { + for (var prop in src) { + if (src.hasOwnProperty(prop) && !dst[prop]) { + dst[prop] = src[prop]; + } + } + return dst; +}; diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/CHANGELOG.md b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/CHANGELOG.md new file mode 100644 index 0000000..f15e081 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/CHANGELOG.md @@ -0,0 +1,125 @@ +# v1.5.2 +- Allow using `"consructor"` as an argument in `memoize` (#998) +- Give a better error messsage when `auto` dependency checking fails (#994) +- Various doc updates (#936, #956, #979, #1002) + +# v1.5.1 +- Fix issue with `pause` in `queue` with concurrency enabled (#946) +- `while` and `until` now pass the final result to callback (#963) +- `auto` will properly handle concurrency when there is no callback (#966) +- `auto` will now properly stop execution when an error occurs (#988, #993) +- Various doc fixes (#971, #980) + +# v1.5.0 + +- Added `transform`, analogous to [`_.transform`](http://lodash.com/docs#transform) (#892) +- `map` now returns an object when an object is passed in, rather than array with non-numeric keys. `map` will begin always returning an array with numeric indexes in the next major release. (#873) +- `auto` now accepts an optional `concurrency` argument to limit the number of running tasks (#637) +- Added `queue#workersList()`, to retrieve the list of currently running tasks. (#891) +- Various code simplifications (#896, #904) +- Various doc fixes :scroll: (#890, #894, #903, #905, #912) + +# v1.4.2 + +- Ensure coverage files don't get published on npm (#879) + +# v1.4.1 + +- Add in overlooked `detectLimit` method (#866) +- Removed unnecessary files from npm releases (#861) +- Removed usage of a reserved word to prevent :boom: in older environments (#870) + +# v1.4.0 + +- `asyncify` now supports promises (#840) +- Added `Limit` versions of `filter` and `reject` (#836) +- Add `Limit` versions of `detect`, `some` and `every` (#828, #829) +- `some`, `every` and `detect` now short circuit early (#828, #829) +- Improve detection of the global object (#804), enabling use in WebWorkers +- `whilst` now called with arguments from iterator (#823) +- `during` now gets called with arguments from iterator (#824) +- Code simplifications and optimizations aplenty ([diff](https://github.com/caolan/async/compare/v1.3.0...v1.4.0)) + + +# v1.3.0 + +New Features: +- Added `constant` +- Added `asyncify`/`wrapSync` for making sync functions work with callbacks. (#671, #806) +- Added `during` and `doDuring`, which are like `whilst` with an async truth test. (#800) +- `retry` now accepts an `interval` parameter to specify a delay between retries. (#793) +- `async` should work better in Web Workers due to better `root` detection (#804) +- Callbacks are now optional in `whilst`, `doWhilst`, `until`, and `doUntil` (#642) +- Various internal updates (#786, #801, #802, #803) +- Various doc fixes (#790, #794) + +Bug Fixes: +- `cargo` now exposes the `payload` size, and `cargo.payload` can be changed on the fly after the `cargo` is created. (#740, #744, #783) + + +# v1.2.1 + +Bug Fix: + +- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782) + + +# v1.2.0 + +New Features: + +- Added `timesLimit` (#743) +- `concurrency` can be changed after initialization in `queue` by setting `q.concurrency`. The new concurrency will be reflected the next time a task is processed. (#747, #772) + +Bug Fixes: + +- Fixed a regression in `each` and family with empty arrays that have additional properties. (#775, #777) + + +# v1.1.1 + +Bug Fix: + +- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. (#782) + + +# v1.1.0 + +New Features: + +- `cargo` now supports all of the same methods and event callbacks as `queue`. +- Added `ensureAsync` - A wrapper that ensures an async function calls its callback on a later tick. (#769) +- Optimized `map`, `eachOf`, and `waterfall` families of functions +- Passing a `null` or `undefined` array to `map`, `each`, `parallel` and families will be treated as an empty array (#667). +- The callback is now optional for the composed results of `compose` and `seq`. (#618) +- Reduced file size by 4kb, (minified version by 1kb) +- Added code coverage through `nyc` and `coveralls` (#768) + +Bug Fixes: + +- `forever` will no longer stack overflow with a synchronous iterator (#622) +- `eachLimit` and other limit functions will stop iterating once an error occurs (#754) +- Always pass `null` in callbacks when there is no error (#439) +- Ensure proper conditions when calling `drain()` after pushing an empty data set to a queue (#668) +- `each` and family will properly handle an empty array (#578) +- `eachSeries` and family will finish if the underlying array is modified during execution (#557) +- `queue` will throw if a non-function is passed to `q.push()` (#593) +- Doc fixes (#629, #766) + + +# v1.0.0 + +No known breaking changes, we are simply complying with semver from here on out. + +Changes: + +- Start using a changelog! +- Add `forEachOf` for iterating over Objects (or to iterate Arrays with indexes available) (#168 #704 #321) +- Detect deadlocks in `auto` (#663) +- Better support for require.js (#527) +- Throw if queue created with concurrency `0` (#714) +- Fix unneeded iteration in `queue.resume()` (#758) +- Guard against timer mocking overriding `setImmediate` (#609 #611) +- Miscellaneous doc fixes (#542 #596 #615 #628 #631 #690 #729) +- Use single noop function internally (#546) +- Optimize internal `_each`, `_map` and `_keys` functions. diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/LICENSE b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/LICENSE new file mode 100644 index 0000000..8f29698 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2014 Caolan McMahon + +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. diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/README.md b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/README.md new file mode 100644 index 0000000..316c405 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/README.md @@ -0,0 +1,1877 @@ +# Async.js + +[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) +[![NPM version](http://img.shields.io/npm/v/async.svg)](https://www.npmjs.org/package/async) +[![Coverage Status](https://coveralls.io/repos/caolan/async/badge.svg?branch=master)](https://coveralls.io/r/caolan/async?branch=master) +[![Join the chat at https://gitter.im/caolan/async](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/caolan/async?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + + +Async is a utility module which provides straight-forward, powerful functions +for working with asynchronous JavaScript. Although originally designed for +use with [Node.js](http://nodejs.org) and installable via `npm install async`, +it can also be used directly in the browser. + +Async is also installable via: + +- [bower](http://bower.io/): `bower install async` +- [component](https://github.com/component/component): `component install + caolan/async` +- [jam](http://jamjs.org/): `jam install async` +- [spm](http://spmjs.io/): `spm install async` + +Async provides around 20 functions that include the usual 'functional' +suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns +for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these +functions assume you follow the Node.js convention of providing a single +callback as the last argument of your `async` function. + + +## Quick Examples + +```javascript +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); + +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); + +async.parallel([ + function(){ ... }, + function(){ ... } +], callback); + +async.series([ + function(){ ... }, + function(){ ... } +]); +``` + +There are many more functions available so take a look at the docs below for a +full list. This module aims to be comprehensive, so if you feel anything is +missing please create a GitHub issue for it. + +## Common Pitfalls [(StackOverflow)](http://stackoverflow.com/questions/tagged/async.js) +### Synchronous iteration functions + +If you get an error like `RangeError: Maximum call stack size exceeded.` or other stack overflow issues when using async, you are likely using a synchronous iterator. By *synchronous* we mean a function that calls its callback on the same tick in the javascript event loop, without doing any I/O or using any timers. Calling many callbacks iteratively will quickly overflow the stack. If you run into this issue, just defer your callback with `async.setImmediate` to start a new call stack on the next tick of the event loop. + +This can also arise by accident if you callback early in certain cases: + +```js +async.eachSeries(hugeArray, function iterator(item, callback) { + if (inCache(item)) { + callback(null, cache[item]); // if many items are cached, you'll overflow + } else { + doSomeIO(item, callback); + } +}, function done() { + //... +}); +``` + +Just change it to: + +```js +async.eachSeries(hugeArray, function iterator(item, callback) { + if (inCache(item)) { + async.setImmediate(function () { + callback(null, cache[item]); + }); + } else { + doSomeIO(item, callback); + //... +``` + +Async guards against synchronous functions in some, but not all, cases. If you are still running into stack overflows, you can defer as suggested above, or wrap functions with [`async.ensureAsync`](#ensureAsync) Functions that are asynchronous by their nature do not have this problem and don't need the extra callback deferral. + +If JavaScript's event loop is still a bit nebulous, check out [this article](http://blog.carbonfive.com/2013/10/27/the-javascript-event-loop-explained/) or [this talk](http://2014.jsconf.eu/speakers/philip-roberts-what-the-heck-is-the-event-loop-anyway.html) for more detailed information about how it works. + + +### Multiple callbacks + +Make sure to always `return` when calling a callback early, otherwise you will cause multiple callbacks and unpredictable behavior in many cases. + +```js +async.waterfall([ + function (callback) { + getSomething(options, function (err, result) { + if (err) { + callback(new Error("failed getting something:" + err.message)); + // we should return here + } + // since we did not return, this callback still will be called and + // `processData` will be called twice + callback(null, result); + }); + }, + processData +], done) +``` + +It is always good practice to `return callback(err, result)` whenever a callback call is not the last statement of a function. + + +### Binding a context to an iterator + +This section is really about `bind`, not about `async`. If you are wondering how to +make `async` execute your iterators in a given context, or are confused as to why +a method of another library isn't working as an iterator, study this example: + +```js +// Here is a simple object with an (unnecessarily roundabout) squaring method +var AsyncSquaringLibrary = { + squareExponent: 2, + square: function(number, callback){ + var result = Math.pow(number, this.squareExponent); + setTimeout(function(){ + callback(null, result); + }, 200); + } +}; + +async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ + // result is [NaN, NaN, NaN] + // This fails because the `this.squareExponent` expression in the square + // function is not evaluated in the context of AsyncSquaringLibrary, and is + // therefore undefined. +}); + +async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ + // result is [1, 4, 9] + // With the help of bind we can attach a context to the iterator before + // passing it to async. Now the square function will be executed in its + // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` + // will be as expected. +}); +``` + +## Download + +The source is available for download from +[GitHub](https://github.com/caolan/async/blob/master/lib/async.js). +Alternatively, you can install using Node Package Manager (`npm`): + + npm install async + +As well as using Bower: + + bower install async + +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed + +## In the Browser + +So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. + +Usage: + +```html + + +``` + +## Documentation + +Some functions are also available in the following forms: +* `Series` - the same as `` but runs only a single async operation at a time +* `Limit` - the same as `` but runs a maximum of `limit` async operations at a time + +### Collections + +* [`each`](#each), `eachSeries`, `eachLimit` +* [`forEachOf`](#forEachOf), `forEachOfSeries`, `forEachOfLimit` +* [`map`](#map), `mapSeries`, `mapLimit` +* [`filter`](#filter), `filterSeries`, `filterLimit` +* [`reject`](#reject), `rejectSeries`, `rejectLimit` +* [`reduce`](#reduce), [`reduceRight`](#reduceRight) +* [`detect`](#detect), `detectSeries`, `detectLimit` +* [`sortBy`](#sortBy) +* [`some`](#some), `someLimit` +* [`every`](#every), `everyLimit` +* [`concat`](#concat), `concatSeries` + +### Control Flow + +* [`series`](#seriestasks-callback) +* [`parallel`](#parallel), `parallelLimit` +* [`whilst`](#whilst), [`doWhilst`](#doWhilst) +* [`until`](#until), [`doUntil`](#doUntil) +* [`during`](#during), [`doDuring`](#doDuring) +* [`forever`](#forever) +* [`waterfall`](#waterfall) +* [`compose`](#compose) +* [`seq`](#seq) +* [`applyEach`](#applyEach), `applyEachSeries` +* [`queue`](#queue), [`priorityQueue`](#priorityQueue) +* [`cargo`](#cargo) +* [`auto`](#auto) +* [`retry`](#retry) +* [`iterator`](#iterator) +* [`times`](#times), `timesSeries`, `timesLimit` + +### Utils + +* [`apply`](#apply) +* [`nextTick`](#nextTick) +* [`memoize`](#memoize) +* [`unmemoize`](#unmemoize) +* [`ensureAsync`](#ensureAsync) +* [`constant`](#constant) +* [`asyncify`](#asyncify) +* [`wrapSync`](#wrapSync) +* [`log`](#log) +* [`dir`](#dir) +* [`noConflict`](#noConflict) + +## Collections + + + +### each(arr, iterator, [callback]) + +Applies the function `iterator` to each item in `arr`, in parallel. +The `iterator` is called with an item from the list, and a callback for when it +has finished. If the `iterator` passes an error to its `callback`, the main +`callback` (for the `each` function) is immediately called with the error. + +Note, that since this function applies `iterator` to each item in parallel, +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occurred, the `callback` should be run without + arguments or with an explicit `null` argument. The array index is not passed + to the iterator. If you need the index, use [`forEachOf`](#forEachOf). +* `callback(err)` - *Optional* A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Examples__ + + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +```js +// assuming openFiles is an array of file names + +async.each(openFiles, function(file, callback) { + + // Perform operation on file here. + console.log('Processing file ' + file); + + if( file.length > 32 ) { + console.log('This file name is too long'); + callback('File name too long'); + } else { + // Do work to process file here + console.log('File processed'); + callback(); + } +}, function(err){ + // if any of the file processing produced an error, err would equal that error + if( err ) { + // One of the iterations produced an error. + // All processing will now stop. + console.log('A file failed to process'); + } else { + console.log('All files have been processed successfully'); + } +}); +``` + +__Related__ + +* eachSeries(arr, iterator, [callback]) +* eachLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + + + +### forEachOf(obj, iterator, [callback]) + +Like `each`, except that it iterates over objects, and passes the key as the second argument to the iterator. + +__Arguments__ + +* `obj` - An object or array to iterate over. +* `iterator(item, key, callback)` - A function to apply to each item in `obj`. +The `key` is the item's key, or index in the case of an array. The iterator is +passed a `callback(err)` which must be called once it has completed. If no +error has occurred, the callback should be run without arguments or with an +explicit `null` argument. +* `callback(err)` - *Optional* A callback which is called when all `iterator` functions have finished, or an error occurs. + +__Example__ + +```js +var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; +var configs = {}; + +async.forEachOf(obj, function (value, key, callback) { + fs.readFile(__dirname + value, "utf8", function (err, data) { + if (err) return callback(err); + try { + configs[key] = JSON.parse(data); + } catch (e) { + return callback(e); + } + callback(); + }) +}, function (err) { + if (err) console.error(err.message); + // configs is now a map of JSON data + doSomethingWith(configs); +}) +``` + +__Related__ + +* forEachOfSeries(obj, iterator, [callback]) +* forEachOfLimit(obj, limit, iterator, [callback]) + +--------------------------------------- + + +### map(arr, iterator, [callback]) + +Produces a new array of values by mapping each value in `arr` through +the `iterator` function. The `iterator` is called with an item from `arr` and a +callback for when it has finished processing. Each of these callback takes 2 arguments: +an `error`, and the transformed item from `arr`. If `iterator` passes an error to its +callback, the main `callback` (for the `map` function) is immediately called with the error. + +Note, that since this function applies the `iterator` to each item in parallel, +there is no guarantee that the `iterator` functions will complete in order. +However, the results array will be in the same order as the original `arr`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - *Optional* A callback which is called when all `iterator` + functions have finished, or an error occurs. Results is an array of the + transformed items from the `arr`. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +__Related__ +* mapSeries(arr, iterator, [callback]) +* mapLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + + +### filter(arr, iterator, [callback]) + +__Alias:__ `select` + +Returns a new array of all the values in `arr` which pass an async truth test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The `iterator` is passed a `callback(truthValue)`, which must be called with a + boolean argument once it has completed. +* `callback(results)` - *Optional* A callback which is called after all the `iterator` + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +__Related__ + +* filterSeries(arr, iterator, [callback]) +* filterLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### reject(arr, iterator, [callback]) + +The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. + +__Related__ + +* rejectSeries(arr, iterator, [callback]) +* rejectLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### reduce(arr, memo, iterator, [callback]) + +__Aliases:__ `inject`, `foldl` + +Reduces `arr` into a single value using an async `iterator` to return +each successive step. `memo` is the initial state of the reduction. +This function only operates in series. + +For performance reasons, it may make sense to split a call to this function into +a parallel map, and then use the normal `Array.prototype.reduce` on the results. +This function is for situations where each step in the reduction needs to be async; +if you can get the data before reducing it, then it's probably a good idea to do so. + +__Arguments__ + +* `arr` - An array to iterate over. +* `memo` - The initial state of the reduction. +* `iterator(memo, item, callback)` - A function applied to each item in the + array to produce the next step in the reduction. The `iterator` is passed a + `callback(err, reduction)` which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main `callback` is + immediately called with the error. +* `callback(err, result)` - *Optional* A callback which is called after all the `iterator` + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, [callback]) + +__Alias:__ `foldr` + +Same as [`reduce`](#reduce), only operates on `arr` in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, [callback]) + +Returns the first value in `arr` that passes an async truth test. The +`iterator` is applied in parallel, meaning the first iterator to return `true` will +fire the detect `callback` with that result. That means the result might not be +the first item in the original `arr` (in terms of order) that passes the test. + +If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries). + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The iterator is passed a `callback(truthValue)` which must be called with a + boolean argument once it has completed. **Note: this callback does not take an error as its first argument.** +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `true`, or after all the `iterator` functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value `undefined` if none passed. **Note: this callback does not take an error as its first argument.** + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +__Related__ + +* detectSeries(arr, iterator, [callback]) +* detectLimit(arr, limit, iterator, [callback]) + +--------------------------------------- + + +### sortBy(arr, iterator, [callback]) + +Sorts a list by the results of running each `arr` value through an async `iterator`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, sortValue)` which must be called once it + has completed with an error (which can be `null`) and a value to use as the sort + criteria. +* `callback(err, results)` - *Optional* A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is the items from + the original `arr` sorted by the values returned by the `iterator` calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +__Sort Order__ + +By modifying the callback parameter the sorting order can be influenced: + +```js +//ascending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x); +}, function(err,result){ + //result callback +} ); + +//descending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(null, x*-1); //<- x*-1 instead of x, turns the order around +}, function(err,result){ + //result callback +} ); +``` + +--------------------------------------- + + +### some(arr, iterator, [callback]) + +__Alias:__ `any` + +Returns `true` if at least one element in the `arr` satisfies an async test. +_The callback for each iterator call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. Once any iterator +call returns `true`, the main `callback` is immediately called. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a `callback(truthValue)`` which must be + called with a boolean argument once it has completed. +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `true`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + + **Note: the callbacks do not take an error as their first argument.** +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +__Related__ + +* someLimit(arr, limit, iterator, callback) + +--------------------------------------- + + +### every(arr, iterator, [callback]) + +__Alias:__ `all` + +Returns `true` if every element in `arr` satisfies an async test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a `callback(truthValue)` which must be + called with a boolean argument once it has completed. +* `callback(result)` - *Optional* A callback which is called as soon as any iterator returns + `false`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + + **Note: the callbacks do not take an error as their first argument.** + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +__Related__ + +* everyLimit(arr, limit, iterator, callback) + +--------------------------------------- + + +### concat(arr, iterator, [callback]) + +Applies `iterator` to each item in `arr`, concatenating the results. Returns the +concatenated list. The `iterator`s are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of `arr` passed to the `iterator` function. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, results)` which must be called once it + has completed with an error (which can be `null`) and an array of results. +* `callback(err, results)` - *Optional* A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is an array containing + the concatenated results of the `iterator` function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +__Related__ + +* concatSeries(arr, iterator, [callback]) + + +## Control Flow + + +### series(tasks, [callback]) + +Run the functions in the `tasks` array in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run, and `callback` is immediately called with the value of the error. +Otherwise, `callback` receives an array of results when `tasks` have completed. + +It is also possible to use an object instead of an array. Each property will be +run as a function, and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`series`](#series). + +**Note** that while many implementations preserve the order of object properties, the +[ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) +explicitly states that + +> The mechanics and order of enumerating the properties is not specified. + +So if you rely on the order in which your series of functions are executed, and want +this to work on all platforms, consider using an array. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run the `tasks` array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main `callback` is immediately called with the value of the error. +Once the `tasks` have completed, the results are passed to the final `callback` as an +array. + +**Note:** `parallel` is about kicking-off I/O tasks in parallel, not about parallel execution of code. If your tasks do not use any timers or perform any I/O, they will actually be executed in series. Any synchronous setup sections for each task will happen one after the other. JavaScript remains single-threaded. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`parallel`](#parallel). + + +__Arguments__ + +* `tasks` - An array or object containing functions to run. Each function is passed + a `callback(err, result)` which it must call on completion with an error `err` + (which can be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed successfully. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +__Related__ + +* parallelLimit(tasks, limit, [callback]) + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +__Arguments__ + +* `test()` - synchronous truth test to perform before each execution of `fn`. +* `fn(callback)` - A function which is called each time `test` passes. The function is + passed a `callback(err)`, which must be called once it has completed with an + optional `err` argument. +* `callback(err, [results])` - A callback which is called after the test + function has failed and repeated execution of `fn` has stopped. `callback` + will be passed an error and any arguments passed to the final `fn`'s callback. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(function () { + callback(null, count); + }, 1000); + }, + function (err, n) { + // 5 seconds have passed, n = 5 + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post-check version of [`whilst`](#whilst). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, +or an error occurs. `callback` will be passed an error and any arguments passed +to the final `fn`'s callback. + +The inverse of [`whilst`](#whilst). + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### during(test, fn, callback) + +Like [`whilst`](#whilst), except the `test` is an asynchronous function that is passed a callback in the form of `function (err, truth)`. If error is passed to `test` or `fn`, the main callback is immediately called with the value of the error. + +__Example__ + +```js +var count = 0; + +async.during( + function (callback) { + return callback(null, count < 5); + }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doDuring(fn, test, callback) + +The post-check version of [`during`](#during). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +Also a version of [`doWhilst`](#doWhilst) with asynchronous `test` function. + +--------------------------------------- + + +### forever(fn, [errback]) + +Calls the asynchronous function `fn` with a callback parameter that allows it to +call itself again, in series, indefinitely. + +If an error is passed to the callback then `errback` is called with the +error, and execution stops, otherwise it will never be called. + +```js +async.forever( + function(next) { + // next is suitable for passing to things that need a callback(err [, whatever]); + // it will result in this function being called again. + }, + function(err) { + // if next is called with a value in its first parameter, it will appear + // in here as 'err', and execution will stop. + } +); +``` + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs the `tasks` array of functions in series, each passing their results to the next in +the array. However, if any of the `tasks` pass an error to their own callback, the +next function is not executed, and the main `callback` is immediately called with +the error. + +__Arguments__ + +* `tasks` - An array of functions to run, each function is passed a + `callback(err, result1, result2, ...)` it must call on completion. The first + argument is an error (which can be `null`) and any further arguments will be + passed as arguments in order to the next task. +* `callback(err, [results])` - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback) { + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); + }, + function(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` +Or, with named functions: + +```js +async.waterfall([ + myFirstFunction, + mySecondFunction, + myLastFunction, +], function (err, result) { + // result now equals 'done' +}); +function myFirstFunction(callback) { + callback(null, 'one', 'two'); +} +function mySecondFunction(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); +} +function myLastFunction(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); +} +``` + +Or, if you need to pass any argument to the first function: + +```js +async.waterfall([ + async.apply(myFirstFunction, 'zero'), + mySecondFunction, + myLastFunction, +], function (err, result) { + // result now equals 'done' +}); +function myFirstFunction(arg1, callback) { + // arg1 now equals 'zero' + callback(null, 'one', 'two'); +} +function mySecondFunction(arg1, arg2, callback) { + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); +} +function myLastFunction(arg1, callback) { + // arg1 now equals 'three' + callback(null, 'done'); +} +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions `f()`, `g()`, and `h()` would produce the result of +`f(g(h()))`, only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### seq(fn1, fn2...) + +Version of the compose function that is more natural to read. +Each function consumes the return value of the previous function. +It is the equivalent of [`compose`](#compose) with the arguments reversed. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +// Requires lodash (or underscore), express3 and dresende's orm2. +// Part of an app, that fetches cats of the logged user. +// This example uses `seq` function to avoid overnesting and error +// handling clutter. +app.get('/cats', function(request, response) { + var User = request.models.User; + async.seq( + _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) + function(user, fn) { + user.getCats(fn); // 'getCats' has signature (callback(err, data)) + } + )(req.session.user_id, function (err, cats) { + if (err) { + console.error(err); + response.json({ status: 'error', message: err.message }); + } else { + response.json({ status: 'ok', message: 'Cats found', data: cats }); + } + }); +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling +`callback` after all functions have completed. If you only provide the first +argument, then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* `fns` - the asynchronous functions to all call with the same arguments +* `args...` - any number of separate arguments to pass to the function +* `callback` - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +__Related__ + +* applyEachSeries(tasks, args..., [callback]) + +--------------------------------------- + + +### queue(worker, [concurrency]) + +Creates a `queue` object with the specified `concurrency`. Tasks added to the +`queue` are processed in parallel (up to the `concurrency` limit). If all +`worker`s are in progress, the task is queued until one becomes available. +Once a `worker` completes a `task`, that `task`'s callback is called. + +__Arguments__ + +* `worker(task, callback)` - An asynchronous function for processing a queued + task, which must call its `callback(err)` argument when finished, with an + optional `error` as an argument. If you want to handle errors from an individual task, pass a callback to `q.push()`. +* `concurrency` - An `integer` for determining how many `worker` functions should be + run in parallel. If omitted, the concurrency defaults to `1`. If the concurrency is `0`, an error is thrown. + +__Queue objects__ + +The `queue` object returned by this function has the following properties and +methods: + +* `length()` - a function returning the number of items waiting to be processed. +* `started` - a function returning whether or not any items have been pushed and processed by the queue +* `running()` - a function returning the number of items currently being processed. +* `workersList()` - a function returning the array of items currently being processed. +* `idle()` - a function returning false if there are items waiting or being processed, or true if not. +* `concurrency` - an integer for determining how many `worker` functions should be + run in parallel. This property can be changed after a `queue` is created to + alter the concurrency on-the-fly. +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once + the `worker` has finished processing the task. Instead of a single task, a `tasks` array + can be submitted. The respective callback is used for every task in the list. +* `unshift(task, [callback])` - add a new task to the front of the `queue`. +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, + and further tasks will be queued. +* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. +* `paused` - a boolean for determining whether the queue is in a paused state +* `pause()` - a function that pauses the processing of tasks until `resume()` is called. +* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. +* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle. + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing item'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + + +--------------------------------------- + + +### priorityQueue(worker, concurrency) + +The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: + +* `push(task, priority, [callback])` - `priority` should be a number. If an array of + `tasks` is given, all tasks will be assigned the same priority. +* The `unshift` method was removed. + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a `cargo` object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the `payload` limit). If the +`worker` is in progress, the task is queued until it becomes available. Once +the `worker` has completed some tasks, each callback of those tasks is called. +Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) for how `cargo` and `queue` work. + +While [queue](#queue) passes only one task to one of a group of workers +at a time, cargo passes an array of tasks to a single worker, repeating +when the worker is finished. + +__Arguments__ + +* `worker(tasks, callback)` - An asynchronous function for processing an array of + queued tasks, which must call its `callback(err)` argument when finished, with + an optional `err` argument. +* `payload` - An optional `integer` for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The `cargo` object returned by this function has the following properties and +methods: + +* `length()` - A function returning the number of items waiting to be processed. +* `payload` - An `integer` for determining how many tasks should be + process per round. This property can be changed after a `cargo` is created to + alter the payload on-the-fly. +* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` + can be submitted. The respective callback is used for every task in the list. +* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. +* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. +* `idle()`, `pause()`, `resume()`, `kill()` - cargo inherits all of the same methods and event calbacks as [`queue`](#queue) + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [concurrency], [callback]) + +Determines the best order for running the functions in `tasks`, based on their requirements. Each function can optionally depend on other functions being completed first, and each function is run as soon as its requirements are satisfied. + +If any of the functions pass an error to their callback, the `auto` sequence will stop. Further tasks will not execute (so any other functions depending on it will not run), and the main `callback` is immediately called with the error. Functions also receive an object containing the results of functions which have completed so far. + +Note, all functions are called with a `results` object as a second argument, +so it is unsafe to pass functions in the `tasks` object which cannot handle the +extra argument. + +For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling `readFile` with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to `readFile` in a function which does not forward the +`results` object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* `tasks` - An object. Each of its properties is either a function or an array of + requirements, with the function itself the last item in the array. The object's key + of a property serves as the name of the task defined by that property, + i.e. can be used when specifying requirements for other tasks. + The function receives two arguments: (1) a `callback(err, result)` which must be + called when finished, passing an `error` (which can be `null`) and the result of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions. +* `concurrency` - An optional `integer` for determining the maximum number of tasks that can be run in parallel. By default, as many as possible. +* `callback(err, results)` - An optional callback which is called when all the + tasks have been completed. It receives the `err` argument if any `tasks` + pass an error to their callback. Results are always returned; however, if + an error occurs, no further `tasks` will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + make_folder: function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + }, + write_file: ['get_data', 'make_folder', function(callback, results){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, 'filename'); + }], + email_link: ['write_file', function(callback, results){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + callback(null, {'file':results.write_file, 'email':'user@example.com'}); + }] +}, function(err, results) { + console.log('err = ', err); + console.log('results = ', results); +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + } +], +function(err, results){ + async.series([ + function(callback){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + results.push('filename'); + callback(null); + }, + function(callback){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + callback(null, {'file':results.pop(), 'email':'user@example.com'}); + } + ]); +}); +``` + +For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding +new tasks much easier (and the code more readable). + + +--------------------------------------- + + +### retry([opts = {times: 5, interval: 0}| 5], task, [callback]) + +Attempts to get a successful response from `task` no more than `times` times before +returning an error. If the task is successful, the `callback` will be passed the result +of the successful task. If all attempts fail, the callback will be passed the error and +result (if any) of the final attempt. + +__Arguments__ + +* `opts` - Can be either an object with `times` and `interval` or a number. + * `times` - The number of attempts to make before giving up. The default is `5`. + * `interval` - The time to wait between retries, in milliseconds. The default is `0`. + * If `opts` is a number, the number specifies the number of times to retry, with the default interval of `0`. +* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` + which must be called when finished, passing `err` (which can be `null`) and the `result` of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions (if nested inside another control flow). +* `callback(err, results)` - An optional callback which is called when the + task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. + +The [`retry`](#retry) function can be used as a stand-alone control flow by passing a callback, as shown below: + +```js +// try calling apiMethod 3 times +async.retry(3, apiMethod, function(err, result) { + // do something with the result +}); +``` + +```js +// try calling apiMethod 3 times, waiting 200 ms between each retry +async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + // do something with the result +}); +``` + +```js +// try calling apiMethod the default 5 times no delay between each retry +async.retry(apiMethod, function(err, result) { + // do something with the result +}); +``` + +It can also be embedded within other control flow functions to retry individual methods +that are not as reliable, like this: + +```js +async.auto({ + users: api.getUsers.bind(api), + payments: async.retry(3, api.getPayments.bind(api)) +}, function(err, results) { + // do something with the results +}); +``` + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the `tasks` array, +returning a continuation to call the next one after that. It's also possible to +“peek” at the next iterator with `iterator.next()`. + +This function is used internally by the `async` module, but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* `tasks` - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied. + +Useful as a shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback), setImmediate(callback) + +Calls `callback` on a later loop around the event loop. In Node.js this just +calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)` +if available, otherwise `setTimeout(callback, 0)`, which means other higher priority +events may precede the execution of `callback`. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* `callback` - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, iterator, [callback]) + +Calls the `iterator` function `n` times, and accumulates results in the same manner +you would use with [`map`](#map). + +__Arguments__ + +* `n` - The number of times to run the function. +* `iterator` - The function to call `n` times. +* `callback` - see [`map`](#map) + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + +__Related__ + +* timesSeries(n, iterator, [callback]) +* timesLimit(n, limit, iterator, [callback]) + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an `async` function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +If no hash function is specified, the first argument is used as a hash key, which may work reasonably if it is a string or a data type that converts to a distinct string. Note that objects and arrays will not behave reasonably. Neither will cases where the other arguments are significant. In such cases, specify your own hash function. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* `fn` - The function to proxy and cache results from. +* `hasher` - An optional function for generating a custom hash for storing + results. It has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized +form. Handy for testing. + +__Arguments__ + +* `fn` - the memoized function + +--------------------------------------- + + +### ensureAsync(fn) + +Wrap an async function and ensure it calls its callback on a later tick of the event loop. If the function already calls its callback on a next tick, no extra deferral is added. This is useful for preventing stack overflows (`RangeError: Maximum call stack size exceeded`) and generally keeping [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) contained. + +__Arguments__ + +* `fn` - an async function, one that expects a node-style callback as its last argument + +Returns a wrapped function with the exact same call signature as the function passed in. + +__Example__ + +```js +function sometimesAsync(arg, callback) { + if (cache[arg]) { + return callback(null, cache[arg]); // this would be synchronous!! + } else { + doSomeIO(arg, callback); // this IO would be asynchronous + } +} + +// this has a risk of stack overflows if many results are cached in a row +async.mapSeries(args, sometimesAsync, done); + +// this will defer sometimesAsync's callback if necessary, +// preventing stack overflows +async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + +``` + +--------------------------------------- + + +### constant(values...) + +Returns a function that when called, calls-back with the values provided. Useful as the first function in a `waterfall`, or for plugging values in to `auto`. + +__Example__ + +```js +async.waterfall([ + async.constant(42), + function (value, next) { + // value === 42 + }, + //... +], callback); + +async.waterfall([ + async.constant(filename, "utf8"), + fs.readFile, + function (fileData, next) { + //... + } + //... +], callback); + +async.auto({ + hostname: async.constant("https://server.net/"), + port: findFreePort, + launchServer: ["hostname", "port", function (cb, options) { + startServer(options, cb); + }], + //... +}, callback); + +``` + +--------------------------------------- + + + +### asyncify(func) + +__Alias:__ `wrapSync` + +Take a sync function and make it async, passing its return value to a callback. This is useful for plugging sync functions into a waterfall, series, or other async functions. Any arguments passed to the generated function will be passed to the wrapped function (except for the final callback argument). Errors thrown will be passed to the callback. + +__Example__ + +```js +async.waterfall([ + async.apply(fs.readFile, filename, "utf8"), + async.asyncify(JSON.parse), + function (data, next) { + // data is the result of parsing the text. + // If there was a parsing error, it would have been caught. + } +], callback) +``` + +If the function passed to `asyncify` returns a Promise, that promises's resolved/rejected state will be used to call the callback, rather than simply the synchronous return value. Example: + +```js +async.waterfall([ + async.apply(fs.readFile, filename, "utf8"), + async.asyncify(function (contents) { + return db.model.create(contents); + }), + function (model, next) { + // `model` is the instantiated model object. + // If there was an error, this function would be skipped. + } +], callback) +``` + +This also means you can asyncify ES2016 `async` functions. + +```js +var q = async.queue(async.asyncify(async function (file) { + var intermediateStep = await processFile(file); + return await somePromise(intermediateStep) +})); + +q.push(files); +``` + +--------------------------------------- + + +### log(function, arguments) + +Logs the result of an `async` function to the `console`. Only works in Node.js or +in browsers that support `console.log` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.log` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an `async` function to the `console` using `console.dir` to +display the properties of the resulting object. Only works in Node.js or +in browsers that support `console.dir` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.dir` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of `async` back to its original value, returning a reference to the +`async` object. diff --git a/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.js b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.js new file mode 100644 index 0000000..31e7620 --- /dev/null +++ b/node_modules/chai-http/node_modules/superagent/node_modules/form-data/node_modules/async/dist/async.js @@ -0,0 +1,1265 @@ +/*! + * async + * https://github.com/caolan/async + * + * Copyright 2010-2014 Caolan McMahon + * Released under the MIT license + */ +(function () { + + var async = {}; + function noop() {} + function identity(v) { + return v; + } + function toBool(v) { + return !!v; + } + function notId(v) { + return !v; + } + + // global on the server, window in the browser + var previous_async; + + // Establish the root object, `window` (`self`) in the browser, `global` + // on the server, or `this` in some virtual machines. We use `self` + // instead of `window` for `WebWorker` support. + var root = typeof self === 'object' && self.self === self && self || + typeof global === 'object' && global.global === global && global || + this; + + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + return function() { + if (fn === null) throw new Error("Callback was already called."); + fn.apply(this, arguments); + fn = null; + }; + } + + function _once(fn) { + return function() { + if (fn === null) return; + fn.apply(this, arguments); + fn = null; + }; + } + + //// cross-browser compatiblity functions //// + + var _toString = Object.prototype.toString; + + var _isArray = Array.isArray || function (obj) { + return _toString.call(obj) === '[object Array]'; + }; + + // Ported from underscore.js isObject + var _isObject = function(obj) { + var type = typeof obj; + return type === 'function' || type === 'object' && !!obj; + }; + + function _isArrayLike(arr) { + return _isArray(arr) || ( + // has a positive integer length property + typeof arr.length === "number" && + arr.length >= 0 && + arr.length % 1 === 0 + ); + } + + function _arrayEach(arr, iterator) { + var index = -1, + length = arr.length; + + while (++index < length) { + iterator(arr[index], index, arr); + } + } + + function _map(arr, iterator) { + var index = -1, + length = arr.length, + result = Array(length); + + while (++index < length) { + result[index] = iterator(arr[index], index, arr); + } + return result; + } + + function _range(count) { + return _map(Array(count), function (v, i) { return i; }); + } + + function _reduce(arr, iterator, memo) { + _arrayEach(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + } + + function _forEachOf(object, iterator) { + _arrayEach(_keys(object), function (key) { + iterator(object[key], key); + }); + } + + function _indexOf(arr, item) { + for (var i = 0; i < arr.length; i++) { + if (arr[i] === item) return i; + } + return -1; + } + + var _keys = Object.keys || function (obj) { + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + function _keyIterator(coll) { + var i = -1; + var len; + var keys; + if (_isArrayLike(coll)) { + len = coll.length; + return function next() { + i++; + return i < len ? i : null; + }; + } else { + keys = _keys(coll); + len = keys.length; + return function next() { + i++; + return i < len ? keys[i] : null; + }; + } + } + + // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html) + // This accumulates the arguments passed into an array, after a given index. + // From underscore.js (https://github.com/jashkenas/underscore/pull/2140). + function _restParam(func, startIndex) { + startIndex = startIndex == null ? func.length - 1 : +startIndex; + return function() { + var length = Math.max(arguments.length - startIndex, 0); + var rest = Array(length); + for (var index = 0; index < length; index++) { + rest[index] = arguments[index + startIndex]; + } + switch (startIndex) { + case 0: return func.call(this, rest); + case 1: return func.call(this, arguments[0], rest); + } + // Currently unused but handle cases outside of the switch statement: + // var args = Array(startIndex + 1); + // for (index = 0; index < startIndex; index++) { + // args[index] = arguments[index]; + // } + // args[startIndex] = rest; + // return func.apply(this, args); + }; + } + + function _withoutIndex(iterator) { + return function (value, index, callback) { + return iterator(value, callback); + }; + } + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + + // capture the global reference to guard against fakeTimer mocks + var _setImmediate = typeof setImmediate === 'function' && setImmediate; + + var _delay = _setImmediate ? function(fn) { + // not a direct alias for IE10 compatibility + _setImmediate(fn); + } : function(fn) { + setTimeout(fn, 0); + }; + + if (typeof process === 'object' && typeof process.nextTick === 'function') { + async.nextTick = process.nextTick; + } else { + async.nextTick = _delay; + } + async.setImmediate = _setImmediate ? _delay : async.nextTick; + + + async.forEach = + async.each = function (arr, iterator, callback) { + return async.eachOf(arr, _withoutIndex(iterator), callback); + }; + + async.forEachSeries = + async.eachSeries = function (arr, iterator, callback) { + return async.eachOfSeries(arr, _withoutIndex(iterator), callback); + }; + + + async.forEachLimit = + async.eachLimit = function (arr, limit, iterator, callback) { + return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback); + }; + + async.forEachOf = + async.eachOf = function (object, iterator, callback) { + callback = _once(callback || noop); + object = object || []; + + var iter = _keyIterator(object); + var key, completed = 0; + + while ((key = iter()) != null) { + completed += 1; + iterator(object[key], key, only_once(done)); + } + + if (completed === 0) callback(null); + + function done(err) { + completed--; + if (err) { + callback(err); + } + // Check key is null in case iterator isn't exhausted + // and done resolved synchronously. + else if (key === null && completed <= 0) { + callback(null); + } + } + }; + + async.forEachOfSeries = + async.eachOfSeries = function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + var key = nextKey(); + function iterate() { + var sync = true; + if (key === null) { + return callback(null); + } + iterator(obj[key], key, only_once(function (err) { + if (err) { + callback(err); + } + else { + key = nextKey(); + if (key === null) { + return callback(null); + } else { + if (sync) { + async.setImmediate(iterate); + } else { + iterate(); + } + } + } + })); + sync = false; + } + iterate(); + }; + + + + async.forEachOfLimit = + async.eachOfLimit = function (obj, limit, iterator, callback) { + _eachOfLimit(limit)(obj, iterator, callback); + }; + + function _eachOfLimit(limit) { + + return function (obj, iterator, callback) { + callback = _once(callback || noop); + obj = obj || []; + var nextKey = _keyIterator(obj); + if (limit <= 0) { + return callback(null); + } + var done = false; + var running = 0; + var errored = false; + + (function replenish () { + if (done && running <= 0) { + return callback(null); + } + + while (running < limit && !errored) { + var key = nextKey(); + if (key === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iterator(obj[key], key, only_once(function (err) { + running -= 1; + if (err) { + callback(err); + errored = true; + } + else { + replenish(); + } + })); + } + })(); + }; + } + + + function doParallel(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOf, obj, iterator, callback); + }; + } + function doParallelLimit(fn) { + return function (obj, limit, iterator, callback) { + return fn(_eachOfLimit(limit), obj, iterator, callback); + }; + } + function doSeries(fn) { + return function (obj, iterator, callback) { + return fn(async.eachOfSeries, obj, iterator, callback); + }; + } + + function _asyncMap(eachfn, arr, iterator, callback) { + callback = _once(callback || noop); + arr = arr || []; + var results = _isArrayLike(arr) ? [] : {}; + eachfn(arr, function (value, index, callback) { + iterator(value, function (err, v) { + results[index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = doParallelLimit(_asyncMap); + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.inject = + async.foldl = + async.reduce = function (arr, memo, iterator, callback) { + async.eachOfSeries(arr, function (x, i, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + + async.foldr = + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, identity).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + + async.transform = function (arr, memo, iterator, callback) { + if (arguments.length === 3) { + callback = iterator; + iterator = memo; + memo = _isArray(arr) ? [] : {}; + } + + async.eachOf(arr, function(v, k, cb) { + iterator(memo, v, k, cb); + }, function(err) { + callback(err, memo); + }); + }; + + function _filter(eachfn, arr, iterator, callback) { + var results = []; + eachfn(arr, function (x, index, callback) { + iterator(x, function (v) { + if (v) { + results.push({index: index, value: x}); + } + callback(); + }); + }, function () { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + } + + async.select = + async.filter = doParallel(_filter); + + async.selectLimit = + async.filterLimit = doParallelLimit(_filter); + + async.selectSeries = + async.filterSeries = doSeries(_filter); + + function _reject(eachfn, arr, iterator, callback) { + _filter(eachfn, arr, function(value, cb) { + iterator(value, function(v) { + cb(!v); + }); + }, callback); + } + async.reject = doParallel(_reject); + async.rejectLimit = doParallelLimit(_reject); + async.rejectSeries = doSeries(_reject); + + function _createTester(eachfn, check, getResult) { + return function(arr, limit, iterator, cb) { + function done() { + if (cb) cb(getResult(false, void 0)); + } + function iteratee(x, _, callback) { + if (!cb) return callback(); + iterator(x, function (v) { + if (cb && check(v)) { + cb(getResult(true, x)); + cb = iterator = false; + } + callback(); + }); + } + if (arguments.length > 3) { + eachfn(arr, limit, iteratee, done); + } else { + cb = iterator; + iterator = limit; + eachfn(arr, iteratee, done); + } + }; + } + + async.any = + async.some = _createTester(async.eachOf, toBool, identity); + + async.someLimit = _createTester(async.eachOfLimit, toBool, identity); + + async.all = + async.every = _createTester(async.eachOf, notId, notId); + + async.everyLimit = _createTester(async.eachOfLimit, notId, notId); + + function _findGetResult(v, x) { + return x; + } + async.detect = _createTester(async.eachOf, identity, _findGetResult); + async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult); + async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult); + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + callback(null, _map(results.sort(comparator), function (x) { + return x.value; + })); + } + + }); + + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } + }; + + async.auto = function (tasks, concurrency, callback) { + if (typeof arguments[1] === 'function') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = _once(callback || noop); + var keys = _keys(tasks); + var remainingTasks = keys.length; + if (!remainingTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = remainingTasks; + } + + var results = {}; + var runningTasks = 0; + + var hasError = false; + + var listeners = []; + function addListener(fn) { + listeners.unshift(fn); + } + function removeListener(fn) { + var idx = _indexOf(listeners, fn); + if (idx >= 0) listeners.splice(idx, 1); + } + function taskComplete() { + remainingTasks--; + _arrayEach(listeners.slice(0), function (fn) { + fn(); + }); + } + + addListener(function () { + if (!remainingTasks) { + callback(null, results); + } + }); + + _arrayEach(keys, function (k) { + if (hasError) return; + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; + var taskCallback = _restParam(function(err, args) { + runningTasks--; + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _forEachOf(results, function(val, rkey) { + safeResults[rkey] = val; + }); + safeResults[k] = args; + hasError = true; + + callback(err, safeResults); + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }); + var requires = task.slice(0, task.length - 1); + // prevent dead-locks + var len = requires.length; + var dep; + while (len--) { + if (!(dep = tasks[requires[len]])) { + throw new Error('Has nonexistent dependency in ' + requires.join(', ')); + } + if (_isArray(dep) && _indexOf(dep, k) >= 0) { + throw new Error('Has cyclic dependencies'); + } + } + function ready() { + return runningTasks < concurrency && _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + } + if (ready()) { + runningTasks++; + task[task.length - 1](taskCallback, results); + } + else { + addListener(listener); + } + function listener() { + if (ready()) { + runningTasks++; + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + } + }); + }; + + + + async.retry = function(times, task, callback) { + var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; + + var attempts = []; + + var opts = { + times: DEFAULT_TIMES, + interval: DEFAULT_INTERVAL + }; + + function parseTimes(acc, t){ + if(typeof t === 'number'){ + acc.times = parseInt(t, 10) || DEFAULT_TIMES; + } else if(typeof t === 'object'){ + acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; + acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; + } else { + throw new Error('Unsupported argument type for \'times\': ' + typeof t); + } + } + + var length = arguments.length; + if (length < 1 || length > 3) { + throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); + } else if (length <= 2 && typeof times === 'function') { + callback = task; + task = times; + } + if (typeof times !== 'function') { + parseTimes(opts, times); + } + opts.callback = callback; + opts.task = task; + + function wrappedTask(wrappedCallback, wrappedResults) { + function retryAttempt(task, finalAttempt) { + return function(seriesCallback) { + task(function(err, result){ + seriesCallback(!err || finalAttempt, {err: err, result: result}); + }, wrappedResults); + }; + } + + function retryInterval(interval){ + return function(seriesCallback){ + setTimeout(function(){ + seriesCallback(null); + }, interval); + }; + } + + while (opts.times) { + + var finalAttempt = !(opts.times-=1); + attempts.push(retryAttempt(opts.task, finalAttempt)); + if(!finalAttempt && opts.interval > 0){ + attempts.push(retryInterval(opts.interval)); + } + } + + async.series(attempts, function(done, data){ + data = data[data.length - 1]; + (wrappedCallback || opts.callback)(data.err, data.result); + }); + } + + // If a callback is passed, run this as a controll flow + return opts.callback ? wrappedTask() : wrappedTask; + }; + + async.waterfall = function (tasks, callback) { + callback = _once(callback || noop); + if (!_isArray(tasks)) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + function wrapIterator(iterator) { + return _restParam(function (err, args) { + if (err) { + callback.apply(null, [err].concat(args)); + } + else { + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + ensureAsync(iterator).apply(null, args); + } + }); + } + wrapIterator(async.iterator(tasks))(); + }; + + function _parallel(eachfn, tasks, callback) { + callback = callback || noop; + var results = _isArrayLike(tasks) ? [] : {}; + + eachfn(tasks, function (task, key, callback) { + task(_restParam(function (err, args) { + if (args.length <= 1) { + args = args[0]; + } + results[key] = args; + callback(err); + })); + }, function (err) { + callback(err, results); + }); + } + + async.parallel = function (tasks, callback) { + _parallel(async.eachOf, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel(_eachOfLimit(limit), tasks, callback); + }; + + async.series = function(tasks, callback) { + _parallel(async.eachOfSeries, tasks, callback); + }; + + async.iterator = function (tasks) { + function makeCallback(index) { + function fn() { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + } + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + } + return makeCallback(0); + }; + + async.apply = _restParam(function (fn, args) { + return _restParam(function (callArgs) { + return fn.apply( + null, args.concat(callArgs) + ); + }); + }); + + function _concat(eachfn, arr, fn, callback) { + var result = []; + eachfn(arr, function (x, index, cb) { + fn(x, function (err, y) { + result = result.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, result); + }); + } + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + callback = callback || noop; + if (test()) { + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else if (test.apply(this, args)) { + iterator(next); + } else { + callback.apply(null, [null].concat(args)); + } + }); + iterator(next); + } else { + callback(null); + } + }; + + async.doWhilst = function (iterator, test, callback) { + var calls = 0; + return async.whilst(function() { + return ++calls <= 1 || test.apply(this, arguments); + }, iterator, callback); + }; + + async.until = function (test, iterator, callback) { + return async.whilst(function() { + return !test.apply(this, arguments); + }, iterator, callback); + }; + + async.doUntil = function (iterator, test, callback) { + return async.doWhilst(iterator, function() { + return !test.apply(this, arguments); + }, callback); + }; + + async.during = function (test, iterator, callback) { + callback = callback || noop; + + var next = _restParam(function(err, args) { + if (err) { + callback(err); + } else { + args.push(check); + test.apply(this, args); + } + }); + + var check = function(err, truth) { + if (err) { + callback(err); + } else if (truth) { + iterator(next); + } else { + callback(null); + } + }; + + test(check); + }; + + async.doDuring = function (iterator, test, callback) { + var calls = 0; + async.during(function(next) { + if (calls++ < 1) { + next(null, true); + } else { + test.apply(this, arguments); + } + }, iterator, callback); + }; + + function _queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new Error('Concurrency must not be zero'); + } + function _insert(q, data, pos, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + callback: callback || noop + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + }); + async.setImmediate(q.process); + } + function _next(q, tasks) { + return function(){ + workers -= 1; + + var removed = false; + var args = arguments; + _arrayEach(tasks, function (task) { + _arrayEach(workersList, function (worker, index) { + if (worker === task && !removed) { + workersList.splice(index, 1); + removed = true; + } + }); + + task.callback.apply(task, args); + }); + if (q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + } + + var workers = 0; + var workersList = []; + var q = { + tasks: [], + concurrency: concurrency, + payload: payload, + saturated: noop, + empty: noop, + drain: noop, + started: false, + paused: false, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + kill: function () { + q.drain = noop; + q.tasks = []; + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + while(!q.paused && workers < q.concurrency && q.tasks.length){ + + var tasks = q.payload ? + q.tasks.splice(0, q.payload) : + q.tasks.splice(0, q.tasks.length); + + var data = _map(tasks, function (task) { + return task.data; + }); + + if (q.tasks.length === 0) { + q.empty(); + } + workers += 1; + workersList.push(tasks[0]); + var cb = only_once(_next(q, tasks)); + worker(data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + }, + workersList: function () { + return workersList; + }, + idle: function() { + return q.tasks.length + workers === 0; + }, + pause: function () { + q.paused = true; + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + var resumeCount = Math.min(q.concurrency, q.tasks.length); + // Need to call q.process once per concurrent + // worker to preserve full concurrency after pause + for (var w = 1; w <= resumeCount; w++) { + async.setImmediate(q.process); + } + } + }; + return q; + } + + async.queue = function (worker, concurrency) { + var q = _queue(function (items, cb) { + worker(items[0], cb); + }, concurrency, 1); + + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; + } + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (callback != null && typeof callback !== "function") { + throw new Error("task callback must be a function"); + } + q.started = true; + if (!_isArray(data)) { + data = [data]; + } + if(data.length === 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + q.drain(); + }); + } + _arrayEach(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : noop + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + // Start with a normal queue + var q = async.queue(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function (data, priority, callback) { + _insert(q, data, priority, callback); + }; + + // Remove unshift function + delete q.unshift; + + return q; + }; + + async.cargo = function (worker, payload) { + return _queue(worker, 1, payload); + }; + + function _console_fn(name) { + return _restParam(function (fn, args) { + fn.apply(null, args.concat([_restParam(function (err, args) { + if (typeof console === 'object') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _arrayEach(args, function (x) { + console[name](x); + }); + } + } + })])); + }); + } + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + var has = Object.prototype.hasOwnProperty; + hasher = hasher || identity; + var memoized = _restParam(function memoized(args) { + var callback = args.pop(); + var key = hasher.apply(null, args); + if (has.call(memo, key)) { + async.setImmediate(function () { + callback.apply(null, memo[key]); + }); + } + else if (has.call(queues, key)) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([_restParam(function (args) { + memo[key] = args; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, args); + } + })])); + } + }); + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + function _times(mapper) { + return function (count, iterator, callback) { + mapper(_range(count), iterator, callback); + }; + } + + async.times = _times(async.map); + async.timesSeries = _times(async.mapSeries); + async.timesLimit = function (count, limit, iterator, callback) { + return async.mapLimit(_range(count), limit, iterator, callback); + }; + + async.seq = function (/* functions... */) { + var fns = arguments; + return _restParam(function (args) { + var that = this; + + var callback = args[args.length - 1]; + if (typeof callback == 'function') { + args.pop(); + } else { + callback = noop; + } + + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([_restParam(function (err, nextargs) { + cb(err, nextargs); + })])); + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }); + }; + + async.compose = function (/* functions... */) { + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + }; + + + function _applyEach(eachfn) { + return _restParam(function(fns, args) { + var go = _restParam(function(args) { + var that = this; + var callback = args.pop(); + return eachfn(fns, function (fn, _, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }); + if (args.length) { + return go.apply(this, args); + } + else { + return go; + } + }); + } + + async.applyEach = _applyEach(async.eachOf); + async.applyEachSeries = _applyEach(async.eachOfSeries); + + + async.forever = function (fn, callback) { + var done = only_once(callback || noop); + var task = ensureAsync(fn); + function next(err) { + if (err) { + return done(err); + } + task(next); + } + next(); + }; + + function ensureAsync(fn) { + return _restParam(function (args) { + var callback = args.pop(); + args.push(function () { + var innerArgs = arguments; + if (sync) { + async.setImmediate(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + var sync = true; + fn.apply(this, args); + sync = false; + }); + } + + async.ensureAsync = ensureAsync; + + async.constant = _restParam(function(values) { + var args = [null].concat(values); + return function (callback) { + return callback.apply(this, args); + }; + }); + + async.wrapSync = + async.asyncify = function asyncify(func) { + return _restParam(function (args) { + var callback = args.pop(); + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (_isObject(result) && typeof result.then === "function") { + result.then(function(value) { + callback(null, value); + })["catch"](function(err) { + callback(err.message ? err : new Error(err)); + }); + } else { + callback(null, result); + } + }); + }; + + // Node.js + if (typeof module === 'object' && module.exports) { + module.exports = async; + } + // AMD / RequireJS + else if (typeof define === 'function' && define.amd) { + define([], function () { + return async; + }); + } + // included directly via diff --git a/node_modules/mocha/lib/reporters/templates/style.html b/node_modules/mocha/lib/reporters/templates/style.html new file mode 100644 index 0000000..4c9c37c --- /dev/null +++ b/node_modules/mocha/lib/reporters/templates/style.html @@ -0,0 +1,324 @@ + diff --git a/node_modules/mocha/lib/reporters/xunit.js b/node_modules/mocha/lib/reporters/xunit.js new file mode 100644 index 0000000..1cfd8f4 --- /dev/null +++ b/node_modules/mocha/lib/reporters/xunit.js @@ -0,0 +1,166 @@ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var inherits = utils.inherits; +var fs = require('fs'); +var escape = utils.escape; +var mkdirp = require('mkdirp'); +var path = require('path'); + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `XUnit`. + */ + +exports = module.exports = XUnit; + +/** + * Initialize a new `XUnit` reporter. + * + * @api public + * @param {Runner} runner + */ +function XUnit(runner, options) { + Base.call(this, runner); + + var stats = this.stats; + var tests = []; + var self = this; + + if (options.reporterOptions && options.reporterOptions.output) { + if (!fs.createWriteStream) { + throw new Error('file output not supported in browser'); + } + mkdirp.sync(path.dirname(options.reporterOptions.output)); + self.fileStream = fs.createWriteStream(options.reporterOptions.output); + } + + runner.on('pending', function(test) { + tests.push(test); + }); + + runner.on('pass', function(test) { + tests.push(test); + }); + + runner.on('fail', function(test) { + tests.push(test); + }); + + runner.on('end', function() { + self.write(tag('testsuite', { + name: 'Mocha Tests', + tests: stats.tests, + failures: stats.failures, + errors: stats.failures, + skipped: stats.tests - stats.failures - stats.passes, + timestamp: (new Date()).toUTCString(), + time: (stats.duration / 1000) || 0 + }, false)); + + tests.forEach(function(t) { + self.test(t); + }); + + self.write(''); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(XUnit, Base); + +/** + * Override done to close the stream (if it's a file). + * + * @param failures + * @param {Function} fn + */ +XUnit.prototype.done = function(failures, fn) { + if (this.fileStream) { + this.fileStream.end(function() { + fn(failures); + }); + } else { + fn(failures); + } +}; + +/** + * Write out the given line. + * + * @param {string} line + */ +XUnit.prototype.write = function(line) { + if (this.fileStream) { + this.fileStream.write(line + '\n'); + } else if (typeof process === 'object' && process.stdout) { + process.stdout.write(line + '\n'); + } else { + console.log(line); + } +}; + +/** + * Output tag for the given `test.` + * + * @param {Test} test + */ +XUnit.prototype.test = function(test) { + var attrs = { + classname: test.parent.fullTitle(), + name: test.title, + time: (test.duration / 1000) || 0 + }; + + if (test.state === 'failed') { + var err = test.err; + this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack)))); + } else if (test.isPending()) { + this.write(tag('testcase', attrs, false, tag('skipped', {}, true))); + } else { + this.write(tag('testcase', attrs, true)); + } +}; + +/** + * HTML tag helper. + * + * @param name + * @param attrs + * @param close + * @param content + * @return {string} + */ +function tag(name, attrs, close, content) { + var end = close ? '/>' : '>'; + var pairs = []; + var tag; + + for (var key in attrs) { + if (Object.prototype.hasOwnProperty.call(attrs, key)) { + pairs.push(key + '="' + escape(attrs[key]) + '"'); + } + } + + tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end; + if (content) { + tag += content + ''; + } + if (key === 'ctx') { + return '#'; + } + return val; + }, 2); +}; + +/** + * Reset the timeout. + * + * @api private + */ +Runnable.prototype.resetTimeout = function() { + var self = this; + var ms = this.timeout() || 1e9; + + if (!this._enableTimeouts) { + return; + } + this.clearTimeout(); + this.timer = setTimeout(function() { + if (!self._enableTimeouts) { + return; + } + self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.')); + self.timedOut = true; + }, ms); +}; + +/** + * Whitelist a list of globals for this test run. + * + * @api private + * @param {string[]} globals + */ +Runnable.prototype.globals = function(globals) { + if (!arguments.length) { + return this._allowedGlobals; + } + this._allowedGlobals = globals; +}; + +/** + * Run the test and invoke `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runnable.prototype.run = function(fn) { + var self = this; + var start = new Date(); + var ctx = this.ctx; + var finished; + var emitted; + + // Sometimes the ctx exists, but it is not runnable + if (ctx && ctx.runnable) { + ctx.runnable(this); + } + + // called multiple times + function multiple(err) { + if (emitted) { + return; + } + emitted = true; + self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate')); + } + + // finished + function done(err) { + var ms = self.timeout(); + if (self.timedOut) { + return; + } + if (finished) { + return multiple(err || self._trace); + } + + self.clearTimeout(); + self.duration = new Date() - start; + finished = true; + if (!err && self.duration > ms && self._enableTimeouts) { + err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'); + } + fn(err); + } + + // for .resetTimeout() + this.callback = done; + + // explicit async with `done` argument + if (this.async) { + this.resetTimeout(); + + if (this.allowUncaught) { + return callFnAsync(this.fn); + } + try { + callFnAsync(this.fn); + } catch (err) { + done(utils.getError(err)); + } + return; + } + + if (this.allowUncaught) { + callFn(this.fn); + done(); + return; + } + + // sync or promise-returning + try { + if (this.isPending()) { + done(); + } else { + callFn(this.fn); + } + } catch (err) { + done(utils.getError(err)); + } + + function callFn(fn) { + var result = fn.call(ctx); + if (result && typeof result.then === 'function') { + self.resetTimeout(); + result + .then(function() { + done(); + // Return null so libraries like bluebird do not warn about + // subsequently constructed Promises. + return null; + }, + function(reason) { + done(reason || new Error('Promise rejected with no or falsy reason')); + }); + } else { + if (self.asyncOnly) { + return done(new Error('--async-only option in use without declaring `done()` or returning a promise')); + } + + done(); + } + } + + function callFnAsync(fn) { + fn.call(ctx, function(err) { + if (err instanceof Error || toString.call(err) === '[object Error]') { + return done(err); + } + if (err) { + if (Object.prototype.toString.call(err) === '[object Object]') { + return done(new Error('done() invoked with non-Error: ' + + JSON.stringify(err))); + } + return done(new Error('done() invoked with non-Error: ' + err)); + } + done(); + }); + } +}; diff --git a/node_modules/mocha/lib/runner.js b/node_modules/mocha/lib/runner.js new file mode 100644 index 0000000..ba4d7df --- /dev/null +++ b/node_modules/mocha/lib/runner.js @@ -0,0 +1,894 @@ +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Pending = require('./pending'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:runner'); +var Runnable = require('./runnable'); +var filter = utils.filter; +var indexOf = utils.indexOf; +var keys = utils.keys; +var stackFilter = utils.stackTraceFilter(); +var stringify = utils.stringify; +var type = utils.type; +var undefinedError = utils.undefinedError; +var isArray = utils.isArray; + +/** + * Non-enumerable globals. + */ + +var globals = [ + 'setTimeout', + 'clearTimeout', + 'setInterval', + 'clearInterval', + 'XMLHttpRequest', + 'Date', + 'setImmediate', + 'clearImmediate' +]; + +/** + * Expose `Runner`. + */ + +module.exports = Runner; + +/** + * Initialize a `Runner` for the given `suite`. + * + * Events: + * + * - `start` execution started + * - `end` execution complete + * - `suite` (suite) test suite execution started + * - `suite end` (suite) all tests (and sub-suites) have finished + * - `test` (test) test execution started + * - `test end` (test) test completed + * - `hook` (hook) hook execution started + * - `hook end` (hook) hook complete + * - `pass` (test) test passed + * - `fail` (test, err) test failed + * - `pending` (test) test pending + * + * @api public + * @param {Suite} suite Root suite + * @param {boolean} [delay] Whether or not to delay execution of root suite + * until ready. + */ +function Runner(suite, delay) { + var self = this; + this._globals = []; + this._abort = false; + this._delay = delay; + this.suite = suite; + this.started = false; + this.total = suite.total(); + this.failures = 0; + this.on('test end', function(test) { + self.checkGlobals(test); + }); + this.on('hook end', function(hook) { + self.checkGlobals(hook); + }); + this._defaultGrep = /.*/; + this.grep(this._defaultGrep); + this.globals(this.globalProps().concat(extraGlobals())); +} + +/** + * Wrapper for setImmediate, process.nextTick, or browser polyfill. + * + * @param {Function} fn + * @api private + */ +Runner.immediately = global.setImmediate || process.nextTick; + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Runner, EventEmitter); + +/** + * Run tests with full titles matching `re`. Updates runner.total + * with number of tests matched. + * + * @param {RegExp} re + * @param {Boolean} invert + * @return {Runner} for chaining + * @api public + * @param {RegExp} re + * @param {boolean} invert + * @return {Runner} Runner instance. + */ +Runner.prototype.grep = function(re, invert) { + debug('grep %s', re); + this._grep = re; + this._invert = invert; + this.total = this.grepTotal(this.suite); + return this; +}; + +/** + * Returns the number of tests matching the grep search for the + * given suite. + * + * @param {Suite} suite + * @return {Number} + * @api public + * @param {Suite} suite + * @return {number} + */ +Runner.prototype.grepTotal = function(suite) { + var self = this; + var total = 0; + + suite.eachTest(function(test) { + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (match) { + total++; + } + }); + + return total; +}; + +/** + * Return a list of global properties. + * + * @return {Array} + * @api private + */ +Runner.prototype.globalProps = function() { + var props = keys(global); + + // non-enumerables + for (var i = 0; i < globals.length; ++i) { + if (~indexOf(props, globals[i])) { + continue; + } + props.push(globals[i]); + } + + return props; +}; + +/** + * Allow the given `arr` of globals. + * + * @param {Array} arr + * @return {Runner} for chaining + * @api public + * @param {Array} arr + * @return {Runner} Runner instance. + */ +Runner.prototype.globals = function(arr) { + if (!arguments.length) { + return this._globals; + } + debug('globals %j', arr); + this._globals = this._globals.concat(arr); + return this; +}; + +/** + * Check for global variable leaks. + * + * @api private + */ +Runner.prototype.checkGlobals = function(test) { + if (this.ignoreLeaks) { + return; + } + var ok = this._globals; + + var globals = this.globalProps(); + var leaks; + + if (test) { + ok = ok.concat(test._allowedGlobals || []); + } + + if (this.prevGlobalsLength === globals.length) { + return; + } + this.prevGlobalsLength = globals.length; + + leaks = filterLeaks(ok, globals); + this._globals = this._globals.concat(leaks); + + if (leaks.length > 1) { + this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + '')); + } else if (leaks.length) { + this.fail(test, new Error('global leak detected: ' + leaks[0])); + } +}; + +/** + * Fail the given `test`. + * + * @api private + * @param {Test} test + * @param {Error} err + */ +Runner.prototype.fail = function(test, err) { + ++this.failures; + test.state = 'failed'; + + if (!(err instanceof Error || err && typeof err.message === 'string')) { + err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)'); + } + + err.stack = (this.fullStackTrace || !err.stack) + ? err.stack + : stackFilter(err.stack); + + this.emit('fail', test, err); +}; + +/** + * Fail the given `hook` with `err`. + * + * Hook failures work in the following pattern: + * - If bail, then exit + * - Failed `before` hook skips all tests in a suite and subsuites, + * but jumps to corresponding `after` hook + * - Failed `before each` hook skips remaining tests in a + * suite and jumps to corresponding `after each` hook, + * which is run only once + * - Failed `after` hook does not alter + * execution order + * - Failed `after each` hook skips remaining tests in a + * suite and subsuites, but executes other `after each` + * hooks + * + * @api private + * @param {Hook} hook + * @param {Error} err + */ +Runner.prototype.failHook = function(hook, err) { + if (hook.ctx && hook.ctx.currentTest) { + hook.originalTitle = hook.originalTitle || hook.title; + hook.title = hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"'; + } + + this.fail(hook, err); + if (this.suite.bail()) { + this.emit('end'); + } +}; + +/** + * Run hook `name` callbacks and then invoke `fn()`. + * + * @api private + * @param {string} name + * @param {Function} fn + */ + +Runner.prototype.hook = function(name, fn) { + var suite = this.suite; + var hooks = suite['_' + name]; + var self = this; + + function next(i) { + var hook = hooks[i]; + if (!hook) { + return fn(); + } + self.currentRunnable = hook; + + hook.ctx.currentTest = self.test; + + self.emit('hook', hook); + + if (!hook.listeners('error').length) { + hook.on('error', function(err) { + self.failHook(hook, err); + }); + } + + hook.run(function(err) { + var testError = hook.error(); + if (testError) { + self.fail(self.test, testError); + } + if (err) { + if (err instanceof Pending) { + suite.pending = true; + } else { + self.failHook(hook, err); + + // stop executing hooks, notify callee of hook err + return fn(err); + } + } + self.emit('hook end', hook); + delete hook.ctx.currentTest; + next(++i); + }); + } + + Runner.immediately(function() { + next(0); + }); +}; + +/** + * Run hook `name` for the given array of `suites` + * in order, and callback `fn(err, errSuite)`. + * + * @api private + * @param {string} name + * @param {Array} suites + * @param {Function} fn + */ +Runner.prototype.hooks = function(name, suites, fn) { + var self = this; + var orig = this.suite; + + function next(suite) { + self.suite = suite; + + if (!suite) { + self.suite = orig; + return fn(); + } + + self.hook(name, function(err) { + if (err) { + var errSuite = self.suite; + self.suite = orig; + return fn(err, errSuite); + } + + next(suites.pop()); + }); + } + + next(suites.pop()); +}; + +/** + * Run hooks from the top level down. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookUp = function(name, fn) { + var suites = [this.suite].concat(this.parents()).reverse(); + this.hooks(name, suites, fn); +}; + +/** + * Run hooks from the bottom up. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookDown = function(name, fn) { + var suites = [this.suite].concat(this.parents()); + this.hooks(name, suites, fn); +}; + +/** + * Return an array of parent Suites from + * closest to furthest. + * + * @return {Array} + * @api private + */ +Runner.prototype.parents = function() { + var suite = this.suite; + var suites = []; + while (suite.parent) { + suite = suite.parent; + suites.push(suite); + } + return suites; +}; + +/** + * Run the current test and callback `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runner.prototype.runTest = function(fn) { + var self = this; + var test = this.test; + + if (this.asyncOnly) { + test.asyncOnly = true; + } + + if (this.allowUncaught) { + test.allowUncaught = true; + return test.run(fn); + } + try { + test.on('error', function(err) { + self.fail(test, err); + }); + test.run(fn); + } catch (err) { + fn(err); + } +}; + +/** + * Run tests in the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runTests = function(suite, fn) { + var self = this; + var tests = suite.tests.slice(); + var test; + + function hookErr(_, errSuite, after) { + // before/after Each hook for errSuite failed: + var orig = self.suite; + + // for failed 'after each' hook start from errSuite parent, + // otherwise start from errSuite itself + self.suite = after ? errSuite.parent : errSuite; + + if (self.suite) { + // call hookUp afterEach + self.hookUp('afterEach', function(err2, errSuite2) { + self.suite = orig; + // some hooks may fail even now + if (err2) { + return hookErr(err2, errSuite2, true); + } + // report error suite + fn(errSuite); + }); + } else { + // there is no need calling other 'after each' hooks + self.suite = orig; + fn(errSuite); + } + } + + function next(err, errSuite) { + // if we bail after first err + if (self.failures && suite._bail) { + return fn(); + } + + if (self._abort) { + return fn(); + } + + if (err) { + return hookErr(err, errSuite, true); + } + + // next test + test = tests.shift(); + + // all done + if (!test) { + return fn(); + } + + // grep + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (!match) { + // Run immediately only if we have defined a grep. When we + // define a grep — It can cause maximum callstack error if + // the grep is doing a large recursive loop by neglecting + // all tests. The run immediately function also comes with + // a performance cost. So we don't want to run immediately + // if we run the whole test suite, because running the whole + // test suite don't do any immediate recursive loops. Thus, + // allowing a JS runtime to breathe. + if (self._grep !== self._defaultGrep) { + Runner.immediately(next); + } else { + next(); + } + return; + } + + if (test.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + + // execute test and hook(s) + self.emit('test', self.test = test); + self.hookDown('beforeEach', function(err, errSuite) { + if (suite.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + if (err) { + return hookErr(err, errSuite, false); + } + self.currentRunnable = self.test; + self.runTest(function(err) { + test = self.test; + if (err) { + var retry = test.currentRetry(); + if (err instanceof Pending) { + test.pending = true; + self.emit('pending', test); + } else if (retry < test.retries()) { + var clonedTest = test.clone(); + clonedTest.currentRetry(retry + 1); + tests.unshift(clonedTest); + + // Early return + hook trigger so that it doesn't + // increment the count wrong + return self.hookUp('afterEach', next); + } else { + self.fail(test, err); + } + self.emit('test end', test); + + if (err instanceof Pending) { + return next(); + } + + return self.hookUp('afterEach', next); + } + + test.state = 'passed'; + self.emit('pass', test); + self.emit('test end', test); + self.hookUp('afterEach', next); + }); + }); + } + + this.next = next; + this.hookErr = hookErr; + next(); +}; + +/** + * Run the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runSuite = function(suite, fn) { + var i = 0; + var self = this; + var total = this.grepTotal(suite); + var afterAllHookCalled = false; + + debug('run suite %s', suite.fullTitle()); + + if (!total || (self.failures && suite._bail)) { + return fn(); + } + + this.emit('suite', this.suite = suite); + + function next(errSuite) { + if (errSuite) { + // current suite failed on a hook from errSuite + if (errSuite === suite) { + // if errSuite is current suite + // continue to the next sibling suite + return done(); + } + // errSuite is among the parents of current suite + // stop execution of errSuite and all sub-suites + return done(errSuite); + } + + if (self._abort) { + return done(); + } + + var curr = suite.suites[i++]; + if (!curr) { + return done(); + } + + // Avoid grep neglecting large number of tests causing a + // huge recursive loop and thus a maximum call stack error. + // See comment in `this.runTests()` for more information. + if (self._grep !== self._defaultGrep) { + Runner.immediately(function() { + self.runSuite(curr, next); + }); + } else { + self.runSuite(curr, next); + } + } + + function done(errSuite) { + self.suite = suite; + self.nextSuite = next; + + if (afterAllHookCalled) { + fn(errSuite); + } else { + // mark that the afterAll block has been called once + // and so can be skipped if there is an error in it. + afterAllHookCalled = true; + + // remove reference to test + delete self.test; + + self.hook('afterAll', function() { + self.emit('suite end', suite); + fn(errSuite); + }); + } + } + + this.nextSuite = next; + + this.hook('beforeAll', function(err) { + if (err) { + return done(); + } + self.runTests(suite, next); + }); +}; + +/** + * Handle uncaught exceptions. + * + * @param {Error} err + * @api private + */ +Runner.prototype.uncaught = function(err) { + if (err) { + debug('uncaught exception %s', err !== function() { + return this; + }.call(err) ? err : (err.message || err)); + } else { + debug('uncaught undefined exception'); + err = undefinedError(); + } + err.uncaught = true; + + var runnable = this.currentRunnable; + + if (!runnable) { + runnable = new Runnable('Uncaught error outside test suite'); + runnable.parent = this.suite; + + if (this.started) { + this.fail(runnable, err); + } else { + // Can't recover from this failure + this.emit('start'); + this.fail(runnable, err); + this.emit('end'); + } + + return; + } + + runnable.clearTimeout(); + + // Ignore errors if complete + if (runnable.state) { + return; + } + this.fail(runnable, err); + + // recover from test + if (runnable.type === 'test') { + this.emit('test end', runnable); + this.hookUp('afterEach', this.next); + return; + } + + // recover from hooks + if (runnable.type === 'hook') { + var errSuite = this.suite; + // if hook failure is in afterEach block + if (runnable.fullTitle().indexOf('after each') > -1) { + return this.hookErr(err, errSuite, true); + } + // if hook failure is in beforeEach block + if (runnable.fullTitle().indexOf('before each') > -1) { + return this.hookErr(err, errSuite, false); + } + // if hook failure is in after or before blocks + return this.nextSuite(errSuite); + } + + // bail + this.emit('end'); +}; + +/** + * Cleans up the references to all the deferred functions + * (before/after/beforeEach/afterEach) and tests of a Suite. + * These must be deleted otherwise a memory leak can happen, + * as those functions may reference variables from closures, + * thus those variables can never be garbage collected as long + * as the deferred functions exist. + * + * @param {Suite} suite + */ +function cleanSuiteReferences(suite) { + function cleanArrReferences(arr) { + for (var i = 0; i < arr.length; i++) { + delete arr[i].fn; + } + } + + if (isArray(suite._beforeAll)) { + cleanArrReferences(suite._beforeAll); + } + + if (isArray(suite._beforeEach)) { + cleanArrReferences(suite._beforeEach); + } + + if (isArray(suite._afterAll)) { + cleanArrReferences(suite._afterAll); + } + + if (isArray(suite._afterEach)) { + cleanArrReferences(suite._afterEach); + } + + for (var i = 0; i < suite.tests.length; i++) { + delete suite.tests[i].fn; + } +} + +/** + * Run the root suite and invoke `fn(failures)` + * on completion. + * + * @param {Function} fn + * @return {Runner} for chaining + * @api public + * @param {Function} fn + * @return {Runner} Runner instance. + */ +Runner.prototype.run = function(fn) { + var self = this; + var rootSuite = this.suite; + + fn = fn || function() {}; + + function uncaught(err) { + self.uncaught(err); + } + + function start() { + self.started = true; + self.emit('start'); + self.runSuite(rootSuite, function() { + debug('finished running'); + self.emit('end'); + }); + } + + debug('start'); + + // references cleanup to avoid memory leaks + this.on('suite end', cleanSuiteReferences); + + // callback + this.on('end', function() { + debug('end'); + process.removeListener('uncaughtException', uncaught); + fn(self.failures); + }); + + // uncaught exception + process.on('uncaughtException', uncaught); + + if (this._delay) { + // for reporters, I guess. + // might be nice to debounce some dots while we wait. + this.emit('waiting', rootSuite); + rootSuite.once('run', start); + } else { + start(); + } + + return this; +}; + +/** + * Cleanly abort execution. + * + * @api public + * @return {Runner} Runner instance. + */ +Runner.prototype.abort = function() { + debug('aborting'); + this._abort = true; + + return this; +}; + +/** + * Filter leaks with the given globals flagged as `ok`. + * + * @api private + * @param {Array} ok + * @param {Array} globals + * @return {Array} + */ +function filterLeaks(ok, globals) { + return filter(globals, function(key) { + // Firefox and Chrome exposes iframes as index inside the window object + if (/^d+/.test(key)) { + return false; + } + + // in firefox + // if runner runs in an iframe, this iframe's window.getInterface method not init at first + // it is assigned in some seconds + if (global.navigator && (/^getInterface/).test(key)) { + return false; + } + + // an iframe could be approached by window[iframeIndex] + // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak + if (global.navigator && (/^\d+/).test(key)) { + return false; + } + + // Opera and IE expose global variables for HTML element IDs (issue #243) + if (/^mocha-/.test(key)) { + return false; + } + + var matched = filter(ok, function(ok) { + if (~ok.indexOf('*')) { + return key.indexOf(ok.split('*')[0]) === 0; + } + return key === ok; + }); + return !matched.length && (!global.navigator || key !== 'onerror'); + }); +} + +/** + * Array of globals dependent on the environment. + * + * @return {Array} + * @api private + */ +function extraGlobals() { + if (typeof process === 'object' && typeof process.version === 'string') { + var parts = process.version.split('.'); + var nodeVersion = utils.reduce(parts, function(a, v) { + return a << 8 | v; + }); + + // 'errno' was renamed to process._errno in v0.9.11. + + if (nodeVersion < 0x00090B) { + return ['errno']; + } + } + + return []; +} diff --git a/node_modules/mocha/lib/suite.js b/node_modules/mocha/lib/suite.js new file mode 100644 index 0000000..d43dd45 --- /dev/null +++ b/node_modules/mocha/lib/suite.js @@ -0,0 +1,395 @@ +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Hook = require('./hook'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:suite'); +var milliseconds = require('./ms'); + +/** + * Expose `Suite`. + */ + +exports = module.exports = Suite; + +/** + * Create a new `Suite` with the given `title` and parent `Suite`. When a suite + * with the same title is already present, that suite is returned to provide + * nicer reporter and more flexible meta-testing. + * + * @api public + * @param {Suite} parent + * @param {string} title + * @return {Suite} + */ +exports.create = function(parent, title) { + var suite = new Suite(title, parent.ctx); + suite.parent = parent; + title = suite.fullTitle(); + parent.addSuite(suite); + return suite; +}; + +/** + * Initialize a new `Suite` with the given `title` and `ctx`. + * + * @api private + * @param {string} title + * @param {Context} parentContext + */ +function Suite(title, parentContext) { + this.title = title; + function Context() {} + Context.prototype = parentContext; + this.ctx = new Context(); + this.suites = []; + this.tests = []; + this.pending = false; + this._beforeEach = []; + this._beforeAll = []; + this._afterEach = []; + this._afterAll = []; + this.root = !title; + this._timeout = 2000; + this._enableTimeouts = true; + this._slow = 75; + this._bail = false; + this._retries = -1; + this.delayed = false; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Suite, EventEmitter); + +/** + * Return a clone of this `Suite`. + * + * @api private + * @return {Suite} + */ +Suite.prototype.clone = function() { + var suite = new Suite(this.title); + debug('clone'); + suite.ctx = this.ctx; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + return suite; +}; + +/** + * Set timeout `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.timeout = function(ms) { + if (!arguments.length) { + return this._timeout; + } + if (ms.toString() === '0') { + this._enableTimeouts = false; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._timeout = parseInt(ms, 10); + return this; +}; + +/** + * Set number of times to retry a failed test. + * + * @api private + * @param {number|string} n + * @return {Suite|number} for chaining + */ +Suite.prototype.retries = function(n) { + if (!arguments.length) { + return this._retries; + } + debug('retries %d', n); + this._retries = parseInt(n, 10) || 0; + return this; +}; + +/** + * Set timeout to `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Suite|boolean} self or enabled + */ +Suite.prototype.enableTimeouts = function(enabled) { + if (!arguments.length) { + return this._enableTimeouts; + } + debug('enableTimeouts %s', enabled); + this._enableTimeouts = enabled; + return this; +}; + +/** + * Set slow `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.slow = function(ms) { + if (!arguments.length) { + return this._slow; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('slow %d', ms); + this._slow = ms; + return this; +}; + +/** + * Sets whether to bail after first error. + * + * @api private + * @param {boolean} bail + * @return {Suite|number} for chaining + */ +Suite.prototype.bail = function(bail) { + if (!arguments.length) { + return this._bail; + } + debug('bail %s', bail); + this._bail = 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. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeAll = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeAll.push(hook); + this.emit('beforeAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after running tests. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterAll = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterAll.push(hook); + this.emit('afterAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` before each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeEach = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeEach.push(hook); + this.emit('beforeEach', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterEach = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterEach.push(hook); + this.emit('afterEach', hook); + return this; +}; + +/** + * Add a test `suite`. + * + * @api private + * @param {Suite} suite + * @return {Suite} for chaining + */ +Suite.prototype.addSuite = function(suite) { + suite.parent = this; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + this.suites.push(suite); + this.emit('suite', suite); + return this; +}; + +/** + * Add a `test` to this suite. + * + * @api private + * @param {Test} test + * @return {Suite} for chaining + */ +Suite.prototype.addTest = function(test) { + test.parent = this; + test.timeout(this.timeout()); + test.retries(this.retries()); + test.enableTimeouts(this.enableTimeouts()); + test.slow(this.slow()); + test.ctx = this.ctx; + this.tests.push(test); + this.emit('test', test); + return this; +}; + +/** + * Return the full title generated by recursively concatenating the parent's + * full title. + * + * @api public + * @return {string} + */ +Suite.prototype.fullTitle = function() { + if (this.parent) { + var full = this.parent.fullTitle(); + if (full) { + return full + ' ' + this.title; + } + } + return this.title; +}; + +/** + * Return the total number of tests. + * + * @api public + * @return {number} + */ +Suite.prototype.total = function() { + return utils.reduce(this.suites, function(sum, suite) { + return sum + suite.total(); + }, 0) + this.tests.length; +}; + +/** + * Iterates through each suite recursively to find all tests. Applies a + * function in the format `fn(test)`. + * + * @api private + * @param {Function} fn + * @return {Suite} + */ +Suite.prototype.eachTest = function(fn) { + utils.forEach(this.tests, fn); + utils.forEach(this.suites, function(suite) { + suite.eachTest(fn); + }); + return this; +}; + +/** + * This will run the root suite if we happen to be running in delayed mode. + */ +Suite.prototype.run = function run() { + if (this.root) { + this.emit('run'); + } +}; diff --git a/node_modules/mocha/lib/template.html b/node_modules/mocha/lib/template.html new file mode 100644 index 0000000..36c5e0b --- /dev/null +++ b/node_modules/mocha/lib/template.html @@ -0,0 +1,18 @@ + + + + Mocha + + + + + +
+ + + + + + diff --git a/node_modules/mocha/lib/test.js b/node_modules/mocha/lib/test.js new file mode 100644 index 0000000..a95cd31 --- /dev/null +++ b/node_modules/mocha/lib/test.js @@ -0,0 +1,44 @@ +/** + * Module dependencies. + */ + +var Runnable = require('./runnable'); +var inherits = require('./utils').inherits; + +/** + * Expose `Test`. + */ + +module.exports = Test; + +/** + * Initialize a new `Test` with the given `title` and callback `fn`. + * + * @api private + * @param {String} title + * @param {Function} fn + */ +function Test(title, fn) { + Runnable.call(this, title, fn); + this.pending = !fn; + this.type = 'test'; +} + +/** + * Inherit from `Runnable.prototype`. + */ +inherits(Test, Runnable); + +Test.prototype.clone = function() { + var test = new Test(this.title, this.fn); + test.timeout(this.timeout()); + test.slow(this.slow()); + test.enableTimeouts(this.enableTimeouts()); + test.retries(this.retries()); + test.currentRetry(this.currentRetry()); + test.globals(this.globals()); + test.parent = this.parent; + test.file = this.file; + test.ctx = this.ctx; + return test; +}; diff --git a/node_modules/mocha/lib/utils.js b/node_modules/mocha/lib/utils.js new file mode 100644 index 0000000..e5d2140 --- /dev/null +++ b/node_modules/mocha/lib/utils.js @@ -0,0 +1,750 @@ +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var basename = require('path').basename; +var debug = require('debug')('mocha:watch'); +var exists = require('fs').existsSync || require('path').existsSync; +var glob = require('glob'); +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. + */ + +var ignore = ['node_modules', '.git']; + +exports.inherits = require('util').inherits; + +/** + * Escape special characters in the given string of html. + * + * @api private + * @param {string} html + * @return {string} + */ +exports.escape = function(html) { + return String(html) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); +}; + +/** + * Array#forEach (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + */ +exports.forEach = function(arr, fn, scope) { + for (var i = 0, l = arr.length; i < l; i++) { + fn.call(scope, arr[i], i); + } +}; + +/** + * Test if the given obj is type of string. + * + * @api private + * @param {Object} obj + * @return {boolean} + */ +exports.isString = function(obj) { + return typeof obj === 'string'; +}; + +/** + * Array#map (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + * @return {Array} + */ +exports.map = function(arr, fn, scope) { + var result = []; + for (var i = 0, l = arr.length; i < l; i++) { + result.push(fn.call(scope, arr[i], i, arr)); + } + return result; +}; + +/** + * Array#indexOf (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Object} obj to find index of + * @param {number} start + * @return {number} + */ +exports.indexOf = function(arr, obj, start) { + for (var i = start || 0, l = arr.length; i < l; i++) { + if (arr[i] === obj) { + return i; + } + } + return -1; +}; + +/** + * Array#reduce (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} val Initial value. + * @return {*} + */ +exports.reduce = function(arr, fn, val) { + var rval = val; + + for (var i = 0, l = arr.length; i < l; i++) { + rval = fn(rval, arr[i], i, arr); + } + + return rval; +}; + +/** + * Array#filter (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @return {Array} + */ +exports.filter = function(arr, fn) { + var ret = []; + + for (var i = 0, l = arr.length; i < l; i++) { + var val = arr[i]; + if (fn(val, i, arr)) { + ret.push(val); + } + } + + return ret; +}; + +/** + * Object.keys (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Array} keys + */ +exports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) { + var keys = []; + var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8 + + for (var key in obj) { + if (has.call(obj, key)) { + keys.push(key); + } + } + + return keys; +}; + +/** + * Watch the given `files` for changes + * and invoke `fn(file)` on modification. + * + * @api private + * @param {Array} files + * @param {Function} fn + */ +exports.watch = function(files, fn) { + var options = { interval: 100 }; + files.forEach(function(file) { + debug('file %s', file); + watchFile(file, options, function(curr, prev) { + if (prev.mtime < curr.mtime) { + fn(file); + } + }); + }); +}; + +/** + * Array.isArray (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Boolean} + */ +var isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +}; + +exports.isArray = isArray; + +/** + * Buffer.prototype.toJSON polyfill. + * + * @type {Function} + */ +if (typeof Buffer !== 'undefined' && Buffer.prototype) { + Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() { + return Array.prototype.slice.call(this, 0); + }; +} + +/** + * Ignored files. + * + * @api private + * @param {string} path + * @return {boolean} + */ +function ignored(path) { + return !~ignore.indexOf(path); +} + +/** + * Lookup files in the given `dir`. + * + * @api private + * @param {string} dir + * @param {string[]} [ext=['.js']] + * @param {Array} [ret=[]] + * @return {Array} + */ +exports.files = function(dir, ext, ret) { + ret = ret || []; + ext = ext || ['js']; + + var re = new RegExp('\\.(' + ext.join('|') + ')$'); + + readdirSync(dir) + .filter(ignored) + .forEach(function(path) { + path = join(dir, path); + if (statSync(path).isDirectory()) { + exports.files(path, ext, ret); + } else if (path.match(re)) { + ret.push(path); + } + }); + + return ret; +}; + +/** + * Compute a slug from the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.slug = function(str) { + return str + .toLowerCase() + .replace(/ +/g, '-') + .replace(/[^-\w]/g, ''); +}; + +/** + * Strip the function definition from `str`, and re-indent for pre whitespace. + * + * @param {string} str + * @return {string} + */ +exports.clean = function(str) { + str = str + .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '') + .replace(/^function *\(.*\)\s*\{|\(.*\) *=> *\{?/, '') + .replace(/\s+\}$/, ''); + + var spaces = str.match(/^\n?( *)/)[1].length; + var tabs = str.match(/^\n?(\t*)/)[1].length; + var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm'); + + str = str.replace(re, ''); + + return exports.trim(str); +}; + +/** + * Trim the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.trim = function(str) { + return str.replace(/^\s+|\s+$/g, ''); +}; + +/** + * Parse the given `qs`. + * + * @api private + * @param {string} qs + * @return {Object} + */ +exports.parseQuery = function(qs) { + return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) { + var i = pair.indexOf('='); + var key = pair.slice(0, i); + var val = pair.slice(++i); + + obj[key] = decodeURIComponent(val); + return obj; + }, {}); +}; + +/** + * Highlight the given string of `js`. + * + * @api private + * @param {string} js + * @return {string} + */ +function highlight(js) { + return js + .replace(//g, '>') + .replace(/\/\/(.*)/gm, '//$1') + .replace(/('.*?')/gm, '$1') + .replace(/(\d+\.\d+)/gm, '$1') + .replace(/(\d+)/gm, '$1') + .replace(/\bnew[ \t]+(\w+)/gm, 'new $1') + .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '$1'); +} + +/** + * Highlight the contents of tag `name`. + * + * @api private + * @param {string} name + */ +exports.highlightTags = function(name) { + var code = document.getElementById('mocha').getElementsByTagName(name); + for (var i = 0, len = code.length; i < len; ++i) { + code[i].innerHTML = highlight(code[i].innerHTML); + } +}; + +/** + * If a value could have properties, and has none, this function is called, + * which returns a string representation of the empty value. + * + * Functions w/ no properties return `'[Function]'` + * Arrays w/ length === 0 return `'[]'` + * Objects w/ no properties return `'{}'` + * All else: return result of `value.toString()` + * + * @api private + * @param {*} value The value to inspect. + * @param {string} [type] The type of the value, if known. + * @returns {string} + */ +function emptyRepresentation(value, type) { + type = type || exports.type(value); + + switch (type) { + case 'function': + return '[Function]'; + case 'object': + return '{}'; + case 'array': + return '[]'; + default: + return value.toString(); + } +} + +/** + * Takes some variable and asks `Object.prototype.toString()` what it thinks it + * is. + * + * @api private + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString + * @param {*} value The value to test. + * @returns {string} + * @example + * type({}) // 'object' + * type([]) // 'array' + * type(1) // 'number' + * type(false) // 'boolean' + * type(Infinity) // 'number' + * type(null) // 'null' + * type(new Date()) // 'date' + * type(/foo/) // 'regexp' + * type('type') // 'string' + * type(global) // 'global' + */ +exports.type = function type(value) { + if (value === undefined) { + return 'undefined'; + } else if (value === null) { + return 'null'; + } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { + return 'buffer'; + } + return Object.prototype.toString.call(value) + .replace(/^\[.+\s(.+?)\]$/, '$1') + .toLowerCase(); +}; + +/** + * Stringify `value`. Different behavior depending on type of value: + * + * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively. + * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes. + * - If `value` is an *empty* object, function, or array, return result of function + * {@link emptyRepresentation}. + * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of + * JSON.stringify(). + * + * @api private + * @see exports.type + * @param {*} value + * @return {string} + */ +exports.stringify = function(value) { + var type = exports.type(value); + + if (!~exports.indexOf(['object', 'array', 'function'], type)) { + if (type !== 'buffer') { + return jsonStringify(value); + } + var json = value.toJSON(); + // Based on the toJSON result + return jsonStringify(json.data && json.type ? json.data : json, 2) + .replace(/,(\n|$)/g, '$1'); + } + + for (var prop in value) { + if (Object.prototype.hasOwnProperty.call(value, prop)) { + return jsonStringify(exports.canonicalize(value), 2).replace(/,(\n|$)/g, '$1'); + } + } + + return emptyRepresentation(value, type); +}; + +/** + * like JSON.stringify but more sense. + * + * @api private + * @param {Object} object + * @param {number=} spaces + * @param {number=} depth + * @returns {*} + */ +function jsonStringify(object, spaces, depth) { + if (typeof spaces === 'undefined') { + // primitive types + return _stringify(object); + } + + depth = depth || 1; + var space = spaces * depth; + var str = isArray(object) ? '[' : '{'; + var end = isArray(object) ? ']' : '}'; + var length = typeof object.length === 'number' ? object.length : exports.keys(object).length; + // `.repeat()` polyfill + function repeat(s, n) { + return new Array(n).join(s); + } + + function _stringify(val) { + switch (exports.type(val)) { + case 'null': + case 'undefined': + val = '[' + val + ']'; + break; + case 'array': + case 'object': + val = jsonStringify(val, spaces, depth + 1); + break; + case 'boolean': + case 'regexp': + case 'symbol': + case 'number': + val = val === 0 && (1 / val) === -Infinity // `-0` + ? '-0' + : val.toString(); + break; + case 'date': + 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': + var json = val.toJSON(); + // Based on the toJSON result + json = json.data && json.type ? json.data : json; + val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']'; + break; + default: + val = (val === '[Function]' || val === '[Circular]') + ? val + : JSON.stringify(val); // string + } + return val; + } + + for (var i in object) { + if (!Object.prototype.hasOwnProperty.call(object, i)) { + continue; // not my business + } + --length; + str += '\n ' + repeat(' ', space) + + (isArray(object) ? '' : '"' + i + '": ') // key + + _stringify(object[i]) // value + + (length ? ',' : ''); // comma + } + + return str + // [], {} + + (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end); +} + +/** + * Test if a value is a buffer. + * + * @api private + * @param {*} value The value to test. + * @return {boolean} True if `value` is a buffer, otherwise false + */ +exports.isBuffer = function(value) { + return typeof Buffer !== 'undefined' && Buffer.isBuffer(value); +}; + +/** + * Return a new Thing that has the keys in sorted order. Recursive. + * + * If the Thing... + * - has already been seen, return string `'[Circular]'` + * - is `undefined`, return string `'[undefined]'` + * - is `null`, return value `null` + * - is some other primitive, return the value + * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method + * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again. + * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()` + * + * @api private + * @see {@link exports.stringify} + * @param {*} value Thing to inspect. May or may not have properties. + * @param {Array} [stack=[]] Stack of seen values + * @return {(Object|Array|Function|string|undefined)} + */ +exports.canonicalize = function(value, stack) { + var canonicalizedObj; + /* eslint-disable no-unused-vars */ + var prop; + /* eslint-enable no-unused-vars */ + var type = exports.type(value); + function withStack(value, fn) { + stack.push(value); + fn(); + stack.pop(); + } + + stack = stack || []; + + if (exports.indexOf(stack, value) !== -1) { + return '[Circular]'; + } + + switch (type) { + case 'undefined': + case 'buffer': + case 'null': + canonicalizedObj = value; + break; + case 'array': + withStack(value, function() { + canonicalizedObj = exports.map(value, function(item) { + return exports.canonicalize(item, stack); + }); + }); + break; + case 'function': + /* eslint-disable guard-for-in */ + for (prop in value) { + canonicalizedObj = {}; + break; + } + /* eslint-enable guard-for-in */ + if (!canonicalizedObj) { + canonicalizedObj = emptyRepresentation(value, type); + break; + } + /* falls through */ + case 'object': + canonicalizedObj = canonicalizedObj || {}; + withStack(value, function() { + exports.forEach(exports.keys(value).sort(), function(key) { + canonicalizedObj[key] = exports.canonicalize(value[key], stack); + }); + }); + break; + case 'date': + case 'number': + case 'regexp': + case 'boolean': + case 'symbol': + canonicalizedObj = value; + break; + default: + canonicalizedObj = value + ''; + } + + return canonicalizedObj; +}; + +/** + * Lookup file names at the given `path`. + * + * @api public + * @param {string} path Base path to start searching from. + * @param {string[]} extensions File extensions to look for. + * @param {boolean} recursive Whether or not to recurse into subdirectories. + * @return {string[]} An array of paths. + */ +exports.lookupFiles = function lookupFiles(path, extensions, recursive) { + var files = []; + var re = new RegExp('\\.(' + extensions.join('|') + ')$'); + + if (!exists(path)) { + if (exists(path + '.js')) { + path += '.js'; + } else { + files = glob.sync(path); + if (!files.length) { + throw new Error("cannot resolve path (or pattern) '" + path + "'"); + } + return files; + } + } + + try { + var stat = statSync(path); + if (stat.isFile()) { + return path; + } + } catch (err) { + // ignore error + return; + } + + readdirSync(path).forEach(function(file) { + file = join(path, file); + try { + var stat = statSync(file); + if (stat.isDirectory()) { + if (recursive) { + files = files.concat(lookupFiles(file, extensions, recursive)); + } + return; + } + } catch (err) { + // ignore error + return; + } + if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') { + return; + } + files.push(file); + }); + + return files; +}; + +/** + * Generate an undefined error with a message warning the user. + * + * @return {Error} + */ + +exports.undefinedError = function() { + return new Error('Caught undefined error, did you throw without specifying what?'); +}; + +/** + * Generate an undefined error if `err` is not defined. + * + * @param {Error} err + * @return {Error} + */ + +exports.getError = function(err) { + return err || exports.undefinedError(); +}; + +/** + * @summary + * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`) + * @description + * When invoking this function you get a filter function that get the Error.stack as an input, + * and return a prettify output. + * (i.e: strip Mocha and internal node functions from stack trace). + * @returns {Function} + */ +exports.stackTraceFilter = function() { + // TODO: Replace with `process.browser` + var slash = '/'; + var is = typeof document === 'undefined' ? { node: true } : { browser: true }; + var cwd = is.node + ? process.cwd() + slash + : (typeof location === 'undefined' ? window.location : location).href.replace(/\/[^\/]*$/, '/'); + + function isMochaInternal(line) { + return (~line.indexOf('node_modules' + slash + 'mocha' + slash)) + || (~line.indexOf('components' + slash + 'mochajs' + slash)) + || (~line.indexOf('components' + slash + 'mocha' + slash)) + || (~line.indexOf(slash + 'mocha.js')); + } + + function isNodeInternal(line) { + return (~line.indexOf('(timers.js:')) + || (~line.indexOf('(events.js:')) + || (~line.indexOf('(node.js:')) + || (~line.indexOf('(module.js:')) + || (~line.indexOf('GeneratorFunctionPrototype.next (native)')) + || false; + } + + return function(stack) { + stack = stack.split('\n'); + + stack = exports.reduce(stack, function(list, line) { + if (isMochaInternal(line)) { + return list; + } + + if (is.node && isNodeInternal(line)) { + return list; + } + + // Clean up cwd(absolute) + if (/\(?.+:\d+:\d+\)?$/.test(line)) { + line = line.replace(cwd, ''); + } + + list.push(line); + return list; + }, []); + + return stack.join('\n'); + }; +}; diff --git a/node_modules/mocha/mocha.css b/node_modules/mocha/mocha.css new file mode 100644 index 0000000..759a6c8 --- /dev/null +++ b/node_modules/mocha/mocha.css @@ -0,0 +1,314 @@ +@charset "utf-8"; + +body { + margin:0; +} + +#mocha { + font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; + margin: 60px 50px; +} + +#mocha ul, +#mocha li { + margin: 0; + padding: 0; +} + +#mocha ul { + list-style: none; +} + +#mocha h1, +#mocha h2 { + margin: 0; +} + +#mocha h1 { + margin-top: 15px; + font-size: 1em; + font-weight: 200; +} + +#mocha h1 a { + text-decoration: none; + color: inherit; +} + +#mocha h1 a:hover { + text-decoration: underline; +} + +#mocha .suite .suite h1 { + margin-top: 0; + font-size: .8em; +} + +#mocha .hidden { + display: none; +} + +#mocha h2 { + font-size: 12px; + font-weight: normal; + cursor: pointer; +} + +#mocha .suite { + margin-left: 15px; +} + +#mocha .test { + margin-left: 15px; + overflow: hidden; +} + +#mocha .test.pending:hover h2::after { + content: '(pending)'; + font-family: arial, sans-serif; +} + +#mocha .test.pass.medium .duration { + background: #c09853; +} + +#mocha .test.pass.slow .duration { + background: #b94a48; +} + +#mocha .test.pass::before { + content: '✓'; + font-size: 12px; + display: block; + float: left; + margin-right: 5px; + color: #00d6b2; +} + +#mocha .test.pass .duration { + font-size: 9px; + margin-left: 5px; + padding: 2px 5px; + color: #fff; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); + -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); + box-shadow: inset 0 1px 1px rgba(0,0,0,.2); + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -ms-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; +} + +#mocha .test.pass.fast .duration { + display: none; +} + +#mocha .test.pending { + color: #0b97c4; +} + +#mocha .test.pending::before { + content: '◦'; + color: #0b97c4; +} + +#mocha .test.fail { + color: #c00; +} + +#mocha .test.fail pre { + color: black; +} + +#mocha .test.fail::before { + content: '✖'; + font-size: 12px; + display: block; + float: left; + margin-right: 5px; + color: #c00; +} + +#mocha .test pre.error { + color: #c00; + max-height: 300px; + overflow: auto; +} + +#mocha .test .html-error { + overflow: auto; + color: black; + line-height: 1.5; + display: block; + float: left; + clear: left; + font: 12px/1.5 monaco, monospace; + margin: 5px; + padding: 15px; + border: 1px solid #eee; + max-width: 85%; /*(1)*/ + max-width: calc(100% - 42px); /*(2)*/ + max-height: 300px; + word-wrap: break-word; + border-bottom-color: #ddd; + -webkit-border-radius: 3px; + -webkit-box-shadow: 0 1px 3px #eee; + -moz-border-radius: 3px; + -moz-box-shadow: 0 1px 3px #eee; + border-radius: 3px; +} + +#mocha .test .html-error pre.error { + border: none; + -webkit-border-radius: none; + -webkit-box-shadow: none; + -moz-border-radius: none; + -moz-box-shadow: none; + padding: 0; + margin: 0; + margin-top: 18px; + max-height: none; +} + +/** + * (1): approximate for browsers not supporting calc + * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border) + * ^^ seriously + */ +#mocha .test pre { + display: block; + float: left; + clear: left; + font: 12px/1.5 monaco, monospace; + margin: 5px; + padding: 15px; + border: 1px solid #eee; + max-width: 85%; /*(1)*/ + max-width: calc(100% - 42px); /*(2)*/ + word-wrap: break-word; + border-bottom-color: #ddd; + -webkit-border-radius: 3px; + -webkit-box-shadow: 0 1px 3px #eee; + -moz-border-radius: 3px; + -moz-box-shadow: 0 1px 3px #eee; + border-radius: 3px; +} + +#mocha .test h2 { + position: relative; +} + +#mocha .test a.replay { + position: absolute; + top: 3px; + right: 0; + text-decoration: none; + vertical-align: middle; + display: block; + width: 15px; + height: 15px; + line-height: 15px; + text-align: center; + background: #eee; + font-size: 15px; + -moz-border-radius: 15px; + border-radius: 15px; + -webkit-transition: opacity 200ms; + -moz-transition: opacity 200ms; + transition: opacity 200ms; + opacity: 0.3; + color: #888; +} + +#mocha .test:hover a.replay { + opacity: 1; +} + +#mocha-report.pass .test.fail { + display: none; +} + +#mocha-report.fail .test.pass { + display: none; +} + +#mocha-report.pending .test.pass, +#mocha-report.pending .test.fail { + display: none; +} +#mocha-report.pending .test.pass.pending { + display: block; +} + +#mocha-error { + color: #c00; + font-size: 1.5em; + font-weight: 100; + letter-spacing: 1px; +} + +#mocha-stats { + position: fixed; + top: 15px; + right: 10px; + font-size: 12px; + margin: 0; + color: #888; + z-index: 1; +} + +#mocha-stats .progress { + float: right; + padding-top: 0; + + /** + * Set safe initial values, so mochas .progress does not inherit these + * properties from Bootstrap .progress (which causes .progress height to + * equal line height set in Bootstrap). + */ + height: auto; + box-shadow: none; + background-color: initial; +} + +#mocha-stats em { + color: black; +} + +#mocha-stats a { + text-decoration: none; + color: inherit; +} + +#mocha-stats a:hover { + border-bottom: 1px solid #eee; +} + +#mocha-stats li { + display: inline-block; + margin: 0 5px; + list-style: none; + padding-top: 11px; +} + +#mocha-stats canvas { + width: 40px; + height: 40px; +} + +#mocha code .comment { color: #ddd; } +#mocha code .init { color: #2f6fad; } +#mocha code .string { color: #5890ad; } +#mocha code .keyword { color: #8a6343; } +#mocha code .number { color: #2f6fad; } + +@media screen and (max-device-width: 480px) { + #mocha { + margin: 60px 0px; + } + + #mocha #stats { + position: absolute; + } +} diff --git a/node_modules/mocha/mocha.js b/node_modules/mocha/mocha.js new file mode 100644 index 0000000..af90ada --- /dev/null +++ b/node_modules/mocha/mocha.js @@ -0,0 +1,13149 @@ +(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 1) { + suites.shift(); + } + var suite = Suite.create(suites[0], title); + suite.file = file; + suites.unshift(suite); + return suite; + }; + + /** + * Exclusive test-case. + */ + + context.suite.only = function(title, fn) { + var suite = context.suite(title, fn); + mocha.grep(suite.fullTitle()); + }; + + /** + * Describe a specification or test-case + * with the given `title` and callback `fn` + * acting as a thunk. + */ + + context.test = function(title, fn) { + var test = new Test(title, fn); + test.file = file; + suites[0].addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.test.only = function(title, fn) { + var test = context.test(title, fn); + var reString = '^' + escapeRe(test.fullTitle()) + '$'; + mocha.grep(new RegExp(reString)); + }; + + context.test.skip = common.test.skip; + context.test.retries = common.test.retries; + }); +}; + +},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":49}],13:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Suite = require('../suite'); +var Test = require('../test'); +var escapeRe = require('escape-string-regexp'); + +/** + * TDD-style interface: + * + * suite('Array', function() { + * suite('#indexOf()', function() { + * suiteSetup(function() { + * + * }); + * + * test('should return -1 when not present', function() { + * + * }); + * + * test('should return the index when present', function() { + * + * }); + * + * suiteTeardown(function() { + * + * }); + * }); + * }); + * + * @param {Suite} suite Root suite. + */ +module.exports = function(suite) { + var suites = [suite]; + + suite.on('pre-require', function(context, file, mocha) { + var common = require('./common')(suites, context); + + context.setup = common.beforeEach; + context.teardown = common.afterEach; + context.suiteSetup = common.before; + context.suiteTeardown = common.after; + context.run = mocha.options.delay && common.runWithSuite(suite); + + /** + * Describe a "suite" with the given `title` and callback `fn` containing + * nested suites and/or tests. + */ + context.suite = function(title, fn) { + var suite = Suite.create(suites[0], title); + suite.file = file; + suites.unshift(suite); + fn.call(suite); + suites.shift(); + return suite; + }; + + /** + * Pending suite. + */ + context.suite.skip = function(title, fn) { + var suite = Suite.create(suites[0], title); + suite.pending = true; + suites.unshift(suite); + fn.call(suite); + suites.shift(); + }; + + /** + * Exclusive test-case. + */ + context.suite.only = function(title, fn) { + var suite = context.suite(title, fn); + mocha.grep(suite.fullTitle()); + }; + + /** + * Describe a specification or test-case with the given `title` and + * callback `fn` acting as a thunk. + */ + context.test = function(title, fn) { + var suite = suites[0]; + if (suite.isPending()) { + fn = null; + } + var test = new Test(title, fn); + test.file = file; + suite.addTest(test); + return test; + }; + + /** + * Exclusive test-case. + */ + + context.test.only = function(title, fn) { + var test = context.test(title, fn); + var reString = '^' + escapeRe(test.fullTitle()) + '$'; + mocha.grep(new RegExp(reString)); + }; + + context.test.skip = common.test.skip; + context.test.retries = common.test.retries; + }); +}; + +},{"../suite":37,"../test":38,"./common":9,"escape-string-regexp":49}],14:[function(require,module,exports){ +(function (process,global,__dirname){ +/*! + * mocha + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var escapeRe = require('escape-string-regexp'); +var path = require('path'); +var reporters = require('./reporters'); +var utils = require('./utils'); + +/** + * Expose `Mocha`. + */ + +exports = module.exports = Mocha; + +/** + * To require local UIs and reporters when running in node. + */ + +if (!process.browser) { + var cwd = process.cwd(); + module.paths.push(cwd, path.join(cwd, 'node_modules')); +} + +/** + * Expose internals. + */ + +exports.utils = utils; +exports.interfaces = require('./interfaces'); +exports.reporters = reporters; +exports.Runnable = require('./runnable'); +exports.Context = require('./context'); +exports.Runner = require('./runner'); +exports.Suite = require('./suite'); +exports.Hook = require('./hook'); +exports.Test = require('./test'); + +/** + * Return image `name` path. + * + * @api private + * @param {string} name + * @return {string} + */ +function image(name) { + return path.join(__dirname, '../images', name + '.png'); +} + +/** + * Set up mocha with `options`. + * + * Options: + * + * - `ui` name "bdd", "tdd", "exports" etc + * - `reporter` reporter instance, defaults to `mocha.reporters.spec` + * - `globals` array of accepted globals + * - `timeout` timeout in milliseconds + * - `retries` number of times to retry failed tests + * - `bail` bail on the first test failure + * - `slow` milliseconds to wait before considering a test slow + * - `ignoreLeaks` ignore global leaks + * - `fullTrace` display the full stack-trace on failing + * - `grep` string or regexp to filter tests with + * + * @param {Object} options + * @api public + */ +function Mocha(options) { + options = options || {}; + this.files = []; + this.options = options; + if (options.grep) { + this.grep(new RegExp(options.grep)); + } + if (options.fgrep) { + this.grep(options.fgrep); + } + this.suite = new exports.Suite('', new exports.Context()); + this.ui(options.ui); + this.bail(options.bail); + this.reporter(options.reporter, options.reporterOptions); + if (typeof options.timeout !== 'undefined' && options.timeout !== null) { + this.timeout(options.timeout); + } + if (typeof options.retries !== 'undefined' && options.retries !== null) { + this.retries(options.retries); + } + this.useColors(options.useColors); + if (options.enableTimeouts !== null) { + this.enableTimeouts(options.enableTimeouts); + } + if (options.slow) { + this.slow(options.slow); + } +} + +/** + * Enable or disable bailing on the first failure. + * + * @api public + * @param {boolean} [bail] + */ +Mocha.prototype.bail = function(bail) { + if (!arguments.length) { + bail = true; + } + this.suite.bail(bail); + return this; +}; + +/** + * Add test `file`. + * + * @api public + * @param {string} file + */ +Mocha.prototype.addFile = function(file) { + this.files.push(file); + return this; +}; + +/** + * Set reporter to `reporter`, defaults to "spec". + * + * @param {String|Function} reporter name or constructor + * @param {Object} reporterOptions optional options + * @api public + * @param {string|Function} reporter name or constructor + * @param {Object} reporterOptions optional options + */ +Mocha.prototype.reporter = function(reporter, reporterOptions) { + if (typeof reporter === 'function') { + this._reporter = reporter; + } else { + reporter = reporter || 'spec'; + var _reporter; + // Try to load a built-in reporter. + if (reporters[reporter]) { + _reporter = reporters[reporter]; + } + // Try to load reporters from process.cwd() and node_modules + if (!_reporter) { + try { + _reporter = require(reporter); + } catch (err) { + err.message.indexOf('Cannot find module') !== -1 + ? console.warn('"' + reporter + '" reporter not found') + : console.warn('"' + reporter + '" reporter blew up with error:\n' + err.stack); + } + } + if (!_reporter && reporter === 'teamcity') { + console.warn('The Teamcity reporter was moved to a package named ' + + 'mocha-teamcity-reporter ' + + '(https://npmjs.org/package/mocha-teamcity-reporter).'); + } + if (!_reporter) { + throw new Error('invalid reporter "' + reporter + '"'); + } + this._reporter = _reporter; + } + this.options.reporterOptions = reporterOptions; + return this; +}; + +/** + * Set test UI `name`, defaults to "bdd". + * + * @api public + * @param {string} bdd + */ +Mocha.prototype.ui = function(name) { + name = name || 'bdd'; + this._ui = exports.interfaces[name]; + if (!this._ui) { + try { + this._ui = require(name); + } catch (err) { + throw new Error('invalid interface "' + 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; +}; + +/** + * Load registered files. + * + * @api private + */ +Mocha.prototype.loadFiles = function(fn) { + var self = this; + var suite = this.suite; + this.files.forEach(function(file) { + file = path.resolve(file); + suite.emit('pre-require', global, file, self); + suite.emit('require', require(file), file, self); + suite.emit('post-require', global, file, self); + }); + fn && fn(); +}; + +/** + * Enable growl support. + * + * @api private + */ +Mocha.prototype._growl = function(runner, reporter) { + var notify = require('growl'); + + runner.on('end', function() { + var stats = reporter.stats; + if (stats.failures) { + var msg = stats.failures + ' of ' + runner.total + ' tests failed'; + notify(msg, { name: 'mocha', title: 'Failed', image: image('error') }); + } else { + notify(stats.passes + ' tests passed in ' + stats.duration + 'ms', { + name: 'mocha', + title: 'Passed', + image: image('ok') + }); + } + }); +}; + +/** + * Add regexp to grep, if `re` is a string it is escaped. + * + * @param {RegExp|String} re + * @return {Mocha} + * @api public + * @param {RegExp|string} re + * @return {Mocha} + */ +Mocha.prototype.grep = function(re) { + this.options.grep = typeof re === 'string' ? new RegExp(escapeRe(re)) : re; + return this; +}; + +/** + * Invert `.grep()` matches. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.invert = function() { + this.options.invert = true; + return this; +}; + +/** + * Ignore global leaks. + * + * @param {Boolean} ignore + * @return {Mocha} + * @api public + * @param {boolean} ignore + * @return {Mocha} + */ +Mocha.prototype.ignoreLeaks = function(ignore) { + this.options.ignoreLeaks = Boolean(ignore); + return this; +}; + +/** + * Enable global leak checking. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.checkLeaks = function() { + this.options.ignoreLeaks = false; + return this; +}; + +/** + * Display long stack-trace on failing + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.fullTrace = function() { + this.options.fullStackTrace = true; + return this; +}; + +/** + * Enable growl support. + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.growl = function() { + this.options.growl = true; + return this; +}; + +/** + * Ignore `globals` array or string. + * + * @param {Array|String} globals + * @return {Mocha} + * @api public + * @param {Array|string} globals + * @return {Mocha} + */ +Mocha.prototype.globals = function(globals) { + this.options.globals = (this.options.globals || []).concat(globals); + return this; +}; + +/** + * Emit color output. + * + * @param {Boolean} colors + * @return {Mocha} + * @api public + * @param {boolean} colors + * @return {Mocha} + */ +Mocha.prototype.useColors = function(colors) { + if (colors !== undefined) { + this.options.useColors = colors; + } + return this; +}; + +/** + * Use inline diffs rather than +/-. + * + * @param {Boolean} inlineDiffs + * @return {Mocha} + * @api public + * @param {boolean} inlineDiffs + * @return {Mocha} + */ +Mocha.prototype.useInlineDiffs = function(inlineDiffs) { + this.options.useInlineDiffs = inlineDiffs !== undefined && inlineDiffs; + return this; +}; + +/** + * Set the timeout in milliseconds. + * + * @param {Number} timeout + * @return {Mocha} + * @api public + * @param {number} timeout + * @return {Mocha} + */ +Mocha.prototype.timeout = function(timeout) { + this.suite.timeout(timeout); + return this; +}; + +/** + * Set the number of times to retry failed tests. + * + * @param {Number} retry times + * @return {Mocha} + * @api public + */ +Mocha.prototype.retries = function(n) { + this.suite.retries(n); + return this; +}; + +/** + * Set slowness threshold in milliseconds. + * + * @param {Number} slow + * @return {Mocha} + * @api public + * @param {number} slow + * @return {Mocha} + */ +Mocha.prototype.slow = function(slow) { + this.suite.slow(slow); + return this; +}; + +/** + * Enable timeouts. + * + * @param {Boolean} enabled + * @return {Mocha} + * @api public + * @param {boolean} enabled + * @return {Mocha} + */ +Mocha.prototype.enableTimeouts = function(enabled) { + this.suite.enableTimeouts(arguments.length && enabled !== undefined ? enabled : true); + return this; +}; + +/** + * Makes all tests async (accepting a callback) + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.asyncOnly = function() { + this.options.asyncOnly = true; + return this; +}; + +/** + * Disable syntax highlighting (in browser). + * + * @api public + */ +Mocha.prototype.noHighlighting = function() { + this.options.noHighlighting = true; + return this; +}; + +/** + * Enable uncaught errors to propagate (in browser). + * + * @return {Mocha} + * @api public + */ +Mocha.prototype.allowUncaught = function() { + this.options.allowUncaught = true; + return this; +}; + +/** + * Delay root suite execution. + * @returns {Mocha} + */ +Mocha.prototype.delay = function delay() { + this.options.delay = true; + return this; +}; + +/** + * Run tests and invoke `fn()` when complete. + * + * @api public + * @param {Function} fn + * @return {Runner} + */ +Mocha.prototype.run = function(fn) { + if (this.files.length) { + this.loadFiles(); + } + var suite = this.suite; + var options = this.options; + options.files = this.files; + var runner = new exports.Runner(suite, options.delay); + var reporter = new this._reporter(runner, options); + runner.ignoreLeaks = options.ignoreLeaks !== false; + runner.fullStackTrace = options.fullStackTrace; + runner.asyncOnly = options.asyncOnly; + runner.allowUncaught = options.allowUncaught; + if (options.grep) { + runner.grep(options.grep, options.invert); + } + if (options.globals) { + runner.globals(options.globals); + } + if (options.growl) { + this._growl(runner, reporter); + } + if (options.useColors !== undefined) { + exports.reporters.Base.useColors = options.useColors; + } + exports.reporters.Base.inlineDiffs = options.useInlineDiffs; + + function done(failures) { + if (reporter.done) { + reporter.done(failures, fn); + } else { + fn && fn(failures); + } + } + + return runner.run(done); +}; + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},"/lib") +},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":22,"./runnable":35,"./runner":36,"./suite":37,"./test":38,"./utils":39,"_process":58,"escape-string-regexp":49,"growl":51,"path":43}],15:[function(require,module,exports){ +/** + * Helpers. + */ + +var s = 1000; +var m = s * 60; +var h = m * 60; +var d = h * 24; +var y = d * 365.25; + +/** + * Parse or format the given `val`. + * + * Options: + * + * - `long` verbose formatting [false] + * + * @api public + * @param {string|number} val + * @param {Object} options + * @return {string|number} + */ +module.exports = function(val, options) { + options = options || {}; + if (typeof val === 'string') { + return parse(val); + } + // https://github.com/mochajs/mocha/pull/1035 + return options['long'] ? longFormat(val) : shortFormat(val); +}; + +/** + * Parse the given `str` and return milliseconds. + * + * @api private + * @param {string} str + * @return {number} + */ +function parse(str) { + var match = (/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?|h|days?|d|years?|y)?$/i).exec(str); + if (!match) { + return; + } + var n = parseFloat(match[1]); + var type = (match[2] || 'ms').toLowerCase(); + switch (type) { + case 'years': + case 'year': + case 'y': + return n * y; + case 'days': + case 'day': + case 'd': + return n * d; + case 'hours': + case 'hour': + case 'h': + return n * h; + case 'minutes': + case 'minute': + case 'm': + return n * m; + case 'seconds': + case 'second': + case 's': + return n * s; + case 'ms': + return n; + default: + // No default case + } +} + +/** + * Short format for `ms`. + * + * @api private + * @param {number} ms + * @return {string} + */ +function shortFormat(ms) { + if (ms >= d) { + return Math.round(ms / d) + 'd'; + } + if (ms >= h) { + return Math.round(ms / h) + 'h'; + } + if (ms >= m) { + return Math.round(ms / m) + 'm'; + } + if (ms >= s) { + return Math.round(ms / s) + 's'; + } + return ms + 'ms'; +} + +/** + * Long format for `ms`. + * + * @api private + * @param {number} ms + * @return {string} + */ +function longFormat(ms) { + return plural(ms, d, 'day') + || plural(ms, h, 'hour') + || plural(ms, m, 'minute') + || plural(ms, s, 'second') + || ms + ' ms'; +} + +/** + * Pluralization helper. + * + * @api private + * @param {number} ms + * @param {number} n + * @param {string} name + */ +function plural(ms, n, name) { + if (ms < n) { + return; + } + if (ms < n * 1.5) { + return Math.floor(ms / n) + ' ' + name; + } + return Math.ceil(ms / n) + ' ' + name + 's'; +} + +},{}],16:[function(require,module,exports){ + +/** + * Expose `Pending`. + */ + +module.exports = Pending; + +/** + * Initialize a new `Pending` error with the given message. + * + * @param {string} message + */ +function Pending(message) { + this.message = message; +} + +},{}],17:[function(require,module,exports){ +(function (process,global){ +/** + * Module dependencies. + */ + +var tty = require('tty'); +var diff = require('diff'); +var ms = require('../ms'); +var utils = require('../utils'); +var supportsColor = process.browser ? null : require('supports-color'); + +/** + * Expose `Base`. + */ + +exports = module.exports = Base; + +/** + * Save timer references to avoid Sinon interfering. + * See: https://github.com/mochajs/mocha/issues/237 + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Check if both stdio streams are associated with a tty. + */ + +var isatty = tty.isatty(1) && tty.isatty(2); + +/** + * Enable coloring by default, except in the browser interface. + */ + +exports.useColors = !process.browser && (supportsColor || (process.env.MOCHA_COLORS !== undefined)); + +/** + * Inline diffs instead of +/- + */ + +exports.inlineDiffs = false; + +/** + * Default color map. + */ + +exports.colors = { + pass: 90, + fail: 31, + 'bright pass': 92, + 'bright fail': 91, + 'bright yellow': 93, + pending: 36, + suite: 0, + 'error title': 0, + 'error message': 31, + 'error stack': 90, + checkmark: 32, + fast: 90, + medium: 33, + slow: 31, + green: 32, + light: 90, + 'diff gutter': 90, + 'diff added': 32, + 'diff removed': 31 +}; + +/** + * Default symbol map. + */ + +exports.symbols = { + ok: '✓', + err: '✖', + dot: '․' +}; + +// With node.js on Windows: use symbols available in terminal default fonts +if (process.platform === 'win32') { + exports.symbols.ok = '\u221A'; + exports.symbols.err = '\u00D7'; + exports.symbols.dot = '.'; +} + +/** + * Color `str` with the given `type`, + * allowing colors to be disabled, + * as well as user-defined color + * schemes. + * + * @param {string} type + * @param {string} str + * @return {string} + * @api private + */ +var color = exports.color = function(type, str) { + if (!exports.useColors) { + return String(str); + } + return '\u001b[' + exports.colors[type] + 'm' + str + '\u001b[0m'; +}; + +/** + * Expose term window size, with some defaults for when stderr is not a tty. + */ + +exports.window = { + width: 75 +}; + +if (isatty) { + exports.window.width = process.stdout.getWindowSize + ? process.stdout.getWindowSize(1)[0] + : tty.getWindowSize()[1]; +} + +/** + * Expose some basic cursor interactions that are common among reporters. + */ + +exports.cursor = { + hide: function() { + isatty && process.stdout.write('\u001b[?25l'); + }, + + show: function() { + isatty && process.stdout.write('\u001b[?25h'); + }, + + deleteLine: function() { + isatty && process.stdout.write('\u001b[2K'); + }, + + beginningOfLine: function() { + isatty && process.stdout.write('\u001b[0G'); + }, + + CR: function() { + if (isatty) { + exports.cursor.deleteLine(); + exports.cursor.beginningOfLine(); + } else { + process.stdout.write('\r'); + } + } +}; + +/** + * Outut the given `failures` as a list. + * + * @param {Array} failures + * @api public + */ + +exports.list = function(failures) { + console.log(); + failures.forEach(function(test, i) { + // format + var fmt = color('error title', ' %s) %s:\n') + + color('error message', ' %s') + + color('error stack', '\n%s\n'); + + // msg + var msg; + var err = test.err; + var message; + if (err.message && typeof err.message.toString === 'function') { + message = err.message + ''; + } else if (typeof err.inspect === 'function') { + message = err.inspect() + ''; + } else { + message = ''; + } + var stack = err.stack || message; + var index = stack.indexOf(message); + var actual = err.actual; + var expected = err.expected; + var escape = true; + + if (index === -1) { + msg = message; + } else { + index += message.length; + msg = stack.slice(0, index); + // remove msg from stack + stack = stack.slice(index + 1); + } + + // uncaught + if (err.uncaught) { + msg = 'Uncaught ' + msg; + } + // explicitly show diff + if (err.showDiff !== false && sameType(actual, expected) && expected !== undefined) { + escape = false; + if (!(utils.isString(actual) && utils.isString(expected))) { + err.actual = actual = utils.stringify(actual); + err.expected = expected = utils.stringify(expected); + } + + fmt = color('error title', ' %s) %s:\n%s') + color('error stack', '\n%s\n'); + var match = message.match(/^([^:]+): expected/); + msg = '\n ' + color('error message', match ? match[1] : msg); + + if (exports.inlineDiffs) { + msg += inlineDiff(err, escape); + } else { + msg += unifiedDiff(err, escape); + } + } + + // indent stack trace + stack = stack.replace(/^/gm, ' '); + + console.log(fmt, (i + 1), test.fullTitle(), msg, stack); + }); +}; + +/** + * Initialize a new `Base` reporter. + * + * All other reporters generally + * inherit from this reporter, providing + * stats such as test duration, number + * of tests passed / failed etc. + * + * @param {Runner} runner + * @api public + */ + +function Base(runner) { + var stats = this.stats = { suites: 0, tests: 0, passes: 0, pending: 0, failures: 0 }; + var failures = this.failures = []; + + if (!runner) { + return; + } + this.runner = runner; + + runner.stats = stats; + + runner.on('start', function() { + stats.start = new Date(); + }); + + runner.on('suite', function(suite) { + stats.suites = stats.suites || 0; + suite.root || stats.suites++; + }); + + runner.on('test end', function() { + stats.tests = stats.tests || 0; + stats.tests++; + }); + + runner.on('pass', function(test) { + stats.passes = stats.passes || 0; + + if (test.duration > test.slow()) { + test.speed = 'slow'; + } else if (test.duration > test.slow() / 2) { + test.speed = 'medium'; + } else { + test.speed = 'fast'; + } + + stats.passes++; + }); + + runner.on('fail', function(test, err) { + stats.failures = stats.failures || 0; + stats.failures++; + test.err = err; + failures.push(test); + }); + + runner.on('end', function() { + stats.end = new Date(); + stats.duration = new Date() - stats.start; + }); + + runner.on('pending', function() { + stats.pending++; + }); +} + +/** + * Output common epilogue used by many of + * the bundled reporters. + * + * @api public + */ +Base.prototype.epilogue = function() { + var stats = this.stats; + var fmt; + + console.log(); + + // passes + fmt = color('bright pass', ' ') + + color('green', ' %d passing') + + color('light', ' (%s)'); + + console.log(fmt, + stats.passes || 0, + ms(stats.duration)); + + // pending + if (stats.pending) { + fmt = color('pending', ' ') + + color('pending', ' %d pending'); + + console.log(fmt, stats.pending); + } + + // failures + if (stats.failures) { + fmt = color('fail', ' %d failing'); + + console.log(fmt, stats.failures); + + Base.list(this.failures); + console.log(); + } + + console.log(); +}; + +/** + * Pad the given `str` to `len`. + * + * @api private + * @param {string} str + * @param {string} len + * @return {string} + */ +function pad(str, len) { + str = String(str); + return Array(len - str.length + 1).join(' ') + str; +} + +/** + * Returns an inline diff between 2 strings with coloured ANSI output + * + * @api private + * @param {Error} err with actual/expected + * @param {boolean} escape + * @return {string} Diff + */ +function inlineDiff(err, escape) { + var msg = errorDiff(err, 'WordsWithSpace', escape); + + // linenos + var lines = msg.split('\n'); + if (lines.length > 4) { + var width = String(lines.length).length; + msg = lines.map(function(str, i) { + return pad(++i, width) + ' |' + ' ' + str; + }).join('\n'); + } + + // legend + msg = '\n' + + color('diff removed', 'actual') + + ' ' + + color('diff added', 'expected') + + '\n\n' + + msg + + '\n'; + + // indent + msg = msg.replace(/^/gm, ' '); + return msg; +} + +/** + * Returns a unified diff between two strings. + * + * @api private + * @param {Error} err with actual/expected + * @param {boolean} escape + * @return {string} The diff. + */ +function unifiedDiff(err, escape) { + var indent = ' '; + function cleanUp(line) { + if (escape) { + line = escapeInvisibles(line); + } + if (line[0] === '+') { + return indent + colorLines('diff added', line); + } + if (line[0] === '-') { + return indent + colorLines('diff removed', line); + } + if (line.match(/\@\@/)) { + return null; + } + if (line.match(/\\ No newline/)) { + return null; + } + return indent + line; + } + function notBlank(line) { + return typeof line !== 'undefined' && line !== null; + } + var msg = diff.createPatch('string', err.actual, err.expected); + var lines = msg.split('\n').splice(4); + return '\n ' + + colorLines('diff added', '+ expected') + ' ' + + colorLines('diff removed', '- actual') + + '\n\n' + + lines.map(cleanUp).filter(notBlank).join('\n'); +} + +/** + * Return a character diff for `err`. + * + * @api private + * @param {Error} err + * @param {string} type + * @param {boolean} escape + * @return {string} + */ +function errorDiff(err, type, escape) { + var actual = escape ? escapeInvisibles(err.actual) : err.actual; + var expected = escape ? escapeInvisibles(err.expected) : err.expected; + return diff['diff' + type](actual, expected).map(function(str) { + if (str.added) { + return colorLines('diff added', str.value); + } + if (str.removed) { + return colorLines('diff removed', str.value); + } + return str.value; + }).join(''); +} + +/** + * Returns a string with all invisible characters in plain text + * + * @api private + * @param {string} line + * @return {string} + */ +function escapeInvisibles(line) { + return line.replace(/\t/g, '') + .replace(/\r/g, '') + .replace(/\n/g, '\n'); +} + +/** + * Color lines for `str`, using the color `name`. + * + * @api private + * @param {string} name + * @param {string} str + * @return {string} + */ +function colorLines(name, str) { + return str.split('\n').map(function(str) { + return color(name, str); + }).join('\n'); +} + +/** + * Object#toString reference. + */ +var objToString = Object.prototype.toString; + +/** + * Check that a / b have the same type. + * + * @api private + * @param {Object} a + * @param {Object} b + * @return {boolean} + */ +function sameType(a, b) { + return objToString.call(a) === objToString.call(b); +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"../ms":15,"../utils":39,"_process":58,"diff":48,"supports-color":43,"tty":5}],18:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); + +/** + * Expose `Doc`. + */ + +exports = module.exports = Doc; + +/** + * Initialize a new `Doc` reporter. + * + * @param {Runner} runner + * @api public + */ +function Doc(runner) { + Base.call(this, runner); + + var indents = 2; + + function indent() { + return Array(indents).join(' '); + } + + runner.on('suite', function(suite) { + if (suite.root) { + return; + } + ++indents; + console.log('%s
', indent()); + ++indents; + console.log('%s

%s

', indent(), utils.escape(suite.title)); + console.log('%s
', indent()); + }); + + runner.on('suite end', function(suite) { + if (suite.root) { + return; + } + console.log('%s
', indent()); + --indents; + console.log('%s
', indent()); + --indents; + }); + + runner.on('pass', function(test) { + console.log('%s
%s
', indent(), utils.escape(test.title)); + var code = utils.escape(utils.clean(test.body)); + console.log('%s
%s
', indent(), code); + }); + + runner.on('fail', function(test, err) { + console.log('%s
%s
', indent(), utils.escape(test.title)); + var code = utils.escape(utils.clean(test.fn.body)); + console.log('%s
%s
', indent(), code); + console.log('%s
%s
', indent(), utils.escape(err)); + }); +} + +},{"../utils":39,"./base":17}],19:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; + +/** + * Expose `Dot`. + */ + +exports = module.exports = Dot; + +/** + * Initialize a new `Dot` matrix test reporter. + * + * @api public + * @param {Runner} runner + */ +function Dot(runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * .75 | 0; + var n = -1; + + runner.on('start', function() { + process.stdout.write('\n'); + }); + + runner.on('pending', function() { + if (++n % width === 0) { + process.stdout.write('\n '); + } + process.stdout.write(color('pending', Base.symbols.dot)); + }); + + runner.on('pass', function(test) { + if (++n % width === 0) { + process.stdout.write('\n '); + } + if (test.speed === 'slow') { + process.stdout.write(color('bright yellow', Base.symbols.dot)); + } else { + process.stdout.write(color(test.speed, Base.symbols.dot)); + } + }); + + runner.on('fail', function() { + if (++n % width === 0) { + process.stdout.write('\n '); + } + process.stdout.write(color('fail', Base.symbols.dot)); + }); + + runner.on('end', function() { + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Dot, Base); + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],20:[function(require,module,exports){ +(function (process,__dirname){ +/** + * Module dependencies. + */ + +var JSONCov = require('./json-cov'); +var readFileSync = require('fs').readFileSync; +var join = require('path').join; + +/** + * Expose `HTMLCov`. + */ + +exports = module.exports = HTMLCov; + +/** + * Initialize a new `JsCoverage` reporter. + * + * @api public + * @param {Runner} runner + */ +function HTMLCov(runner) { + var jade = require('jade'); + var file = join(__dirname, '/templates/coverage.jade'); + var str = readFileSync(file, 'utf8'); + var fn = jade.compile(str, { filename: file }); + var self = this; + + JSONCov.call(this, runner, false); + + runner.on('end', function() { + process.stdout.write(fn({ + cov: self.cov, + coverageClass: coverageClass + })); + }); +} + +/** + * Return coverage class for a given coverage percentage. + * + * @api private + * @param {number} coveragePctg + * @return {string} + */ +function coverageClass(coveragePctg) { + if (coveragePctg >= 75) { + return 'high'; + } + if (coveragePctg >= 50) { + return 'medium'; + } + if (coveragePctg >= 25) { + return 'low'; + } + return 'terrible'; +} + +}).call(this,require('_process'),"/lib/reporters") +},{"./json-cov":23,"_process":58,"fs":43,"jade":43,"path":43}],21:[function(require,module,exports){ +(function (global){ +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var Progress = require('../browser/progress'); +var escapeRe = require('escape-string-regexp'); +var escape = utils.escape; + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `HTML`. + */ + +exports = module.exports = HTML; + +/** + * Stats template. + */ + +var statsTemplate = '
'; + +/** + * Initialize a new `HTML` reporter. + * + * @api public + * @param {Runner} runner + */ +function HTML(runner) { + Base.call(this, runner); + + var self = this; + var stats = this.stats; + var stat = fragment(statsTemplate); + var items = stat.getElementsByTagName('li'); + var passes = items[1].getElementsByTagName('em')[0]; + var passesLink = items[1].getElementsByTagName('a')[0]; + var failures = items[2].getElementsByTagName('em')[0]; + var failuresLink = items[2].getElementsByTagName('a')[0]; + var duration = items[3].getElementsByTagName('em')[0]; + var canvas = stat.getElementsByTagName('canvas')[0]; + var report = fragment('
    '); + var stack = [report]; + var progress; + var ctx; + var root = document.getElementById('mocha'); + + if (canvas.getContext) { + var ratio = window.devicePixelRatio || 1; + canvas.style.width = canvas.width; + canvas.style.height = canvas.height; + canvas.width *= ratio; + canvas.height *= ratio; + ctx = canvas.getContext('2d'); + ctx.scale(ratio, ratio); + progress = new Progress(); + } + + if (!root) { + return error('#mocha div missing, add it to your document'); + } + + // pass toggle + on(passesLink, 'click', function(evt) { + evt.preventDefault(); + unhide(); + var name = (/pass/).test(report.className) ? '' : ' pass'; + report.className = report.className.replace(/fail|pass/g, '') + name; + if (report.className.trim()) { + hideSuitesWithout('test pass'); + } + }); + + // failure toggle + on(failuresLink, 'click', function(evt) { + evt.preventDefault(); + unhide(); + var name = (/fail/).test(report.className) ? '' : ' fail'; + report.className = report.className.replace(/fail|pass/g, '') + name; + if (report.className.trim()) { + hideSuitesWithout('test fail'); + } + }); + + root.appendChild(stat); + root.appendChild(report); + + if (progress) { + progress.size(40); + } + + runner.on('suite', function(suite) { + if (suite.root) { + return; + } + + // suite + var url = self.suiteURL(suite); + var el = fragment('
  • %s

  • ', url, escape(suite.title)); + + // container + stack[0].appendChild(el); + stack.unshift(document.createElement('ul')); + el.appendChild(stack[0]); + }); + + runner.on('suite end', function(suite) { + if (suite.root) { + return; + } + stack.shift(); + }); + + runner.on('pass', function(test) { + var url = self.testURL(test); + var markup = '
  • %e%ems ' + + '

  • '; + var el = fragment(markup, test.speed, test.title, test.duration, url); + self.addCodeToggle(el, test.body); + appendToStack(el); + updateStats(); + }); + + runner.on('fail', function(test) { + var el = fragment('
  • %e

  • ', + test.title, self.testURL(test)); + var stackString; // Note: Includes leading newline + var message = test.err.toString(); + + // <=IE7 stringifies to [Object Error]. Since it can be overloaded, we + // check for the result of the stringifying. + if (message === '[object Error]') { + message = test.err.message; + } + + if (test.err.stack) { + var indexOfMessage = test.err.stack.indexOf(test.err.message); + if (indexOfMessage === -1) { + stackString = test.err.stack; + } else { + stackString = test.err.stack.substr(test.err.message.length + indexOfMessage); + } + } else if (test.err.sourceURL && test.err.line !== undefined) { + // Safari doesn't give you a stack. Let's at least provide a source line. + stackString = '\n(' + test.err.sourceURL + ':' + test.err.line + ')'; + } + + stackString = stackString || ''; + + if (test.err.htmlMessage && stackString) { + el.appendChild(fragment('
    %s\n
    %e
    ', + test.err.htmlMessage, stackString)); + } else if (test.err.htmlMessage) { + el.appendChild(fragment('
    %s
    ', test.err.htmlMessage)); + } else { + el.appendChild(fragment('
    %e%e
    ', message, stackString)); + } + + self.addCodeToggle(el, test.body); + appendToStack(el); + updateStats(); + }); + + runner.on('pending', function(test) { + var el = fragment('
  • %e

  • ', test.title); + appendToStack(el); + updateStats(); + }); + + function appendToStack(el) { + // Don't call .appendChild if #mocha-report was already .shift()'ed off the stack. + if (stack[0]) { + stack[0].appendChild(el); + } + } + + function updateStats() { + // TODO: add to stats + var percent = stats.tests / this.total * 100 | 0; + if (progress) { + progress.update(percent).draw(ctx); + } + + // update stats + var ms = new Date() - stats.start; + text(passes, stats.passes); + text(failures, stats.failures); + text(duration, (ms / 1000).toFixed(2)); + } +} + +/** + * Makes a URL, preserving querystring ("search") parameters. + * + * @param {string} s + * @return {string} A new URL. + */ +function makeUrl(s) { + var search = window.location.search; + + // Remove previous grep query parameter if present + if (search) { + search = search.replace(/[?&]grep=[^&\s]*/g, '').replace(/^&/, '?'); + } + + return window.location.pathname + (search ? search + '&' : '?') + 'grep=' + encodeURIComponent(escapeRe(s)); +} + +/** + * Provide suite URL. + * + * @param {Object} [suite] + */ +HTML.prototype.suiteURL = function(suite) { + return makeUrl(suite.fullTitle()); +}; + +/** + * Provide test URL. + * + * @param {Object} [test] + */ +HTML.prototype.testURL = function(test) { + return makeUrl(test.fullTitle()); +}; + +/** + * Adds code toggle functionality for the provided test's list element. + * + * @param {HTMLLIElement} el + * @param {string} contents + */ +HTML.prototype.addCodeToggle = function(el, contents) { + var h2 = el.getElementsByTagName('h2')[0]; + + on(h2, 'click', function() { + pre.style.display = pre.style.display === 'none' ? 'block' : 'none'; + }); + + var pre = fragment('
    %e
    ', utils.clean(contents)); + el.appendChild(pre); + pre.style.display = 'none'; +}; + +/** + * Display error `msg`. + * + * @param {string} msg + */ +function error(msg) { + document.body.appendChild(fragment('
    %s
    ', msg)); +} + +/** + * Return a DOM fragment from `html`. + * + * @param {string} html + */ +function fragment(html) { + var args = arguments; + var div = document.createElement('div'); + var i = 1; + + div.innerHTML = html.replace(/%([se])/g, function(_, type) { + switch (type) { + case 's': return String(args[i++]); + case 'e': return escape(args[i++]); + // no default + } + }); + + return div.firstChild; +} + +/** + * Check for suites that do not have elements + * with `classname`, and hide them. + * + * @param {text} classname + */ +function hideSuitesWithout(classname) { + var suites = document.getElementsByClassName('suite'); + for (var i = 0; i < suites.length; i++) { + var els = suites[i].getElementsByClassName(classname); + if (!els.length) { + suites[i].className += ' hidden'; + } + } +} + +/** + * Unhide .hidden suites. + */ +function unhide() { + var els = document.getElementsByClassName('suite hidden'); + for (var i = 0; i < els.length; ++i) { + els[i].className = els[i].className.replace('suite hidden', 'suite'); + } +} + +/** + * Set an element's text contents. + * + * @param {HTMLElement} el + * @param {string} contents + */ +function text(el, contents) { + if (el.textContent) { + el.textContent = contents; + } else { + el.innerText = contents; + } +} + +/** + * Listen on `event` with callback `fn`. + */ +function on(el, event, fn) { + if (el.addEventListener) { + el.addEventListener(event, fn, false); + } else { + el.attachEvent('on' + 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":49}],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'); +exports.Dot = exports.dot = require('./dot'); +exports.Doc = exports.doc = require('./doc'); +exports.TAP = exports.tap = require('./tap'); +exports.JSON = exports.json = require('./json'); +exports.HTML = exports.html = require('./html'); +exports.List = exports.list = require('./list'); +exports.Min = exports.min = require('./min'); +exports.Spec = exports.spec = require('./spec'); +exports.Nyan = exports.nyan = require('./nyan'); +exports.XUnit = exports.xunit = require('./xunit'); +exports.Markdown = exports.markdown = require('./markdown'); +exports.Progress = exports.progress = require('./progress'); +exports.Landing = exports.landing = require('./landing'); +exports.JSONCov = exports['json-cov'] = require('./json-cov'); +exports.HTMLCov = exports['html-cov'] = require('./html-cov'); +exports.JSONStream = exports['json-stream'] = require('./json-stream'); + +},{"./base":17,"./doc":18,"./dot":19,"./html":21,"./html-cov":20,"./json":25,"./json-cov":23,"./json-stream":24,"./landing":26,"./list":27,"./markdown":28,"./min":29,"./nyan":30,"./progress":31,"./spec":32,"./tap":33,"./xunit":34}],23:[function(require,module,exports){ +(function (process,global){ +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `JSONCov`. + */ + +exports = module.exports = JSONCov; + +/** + * Initialize a new `JsCoverage` reporter. + * + * @api public + * @param {Runner} runner + * @param {boolean} output + */ +function JSONCov(runner, output) { + Base.call(this, runner); + + output = arguments.length === 1 || output; + var self = this; + var tests = []; + var failures = []; + var passes = []; + + runner.on('test end', function(test) { + tests.push(test); + }); + + runner.on('pass', function(test) { + passes.push(test); + }); + + runner.on('fail', function(test) { + failures.push(test); + }); + + runner.on('end', function() { + var cov = global._$jscoverage || {}; + var result = self.cov = map(cov); + result.stats = self.stats; + result.tests = tests.map(clean); + result.failures = failures.map(clean); + result.passes = passes.map(clean); + if (!output) { + return; + } + process.stdout.write(JSON.stringify(result, null, 2)); + }); +} + +/** + * Map jscoverage data to a JSON structure + * suitable for reporting. + * + * @api private + * @param {Object} cov + * @return {Object} + */ + +function map(cov) { + var ret = { + instrumentation: 'node-jscoverage', + sloc: 0, + hits: 0, + misses: 0, + coverage: 0, + files: [] + }; + + for (var filename in cov) { + if (Object.prototype.hasOwnProperty.call(cov, filename)) { + var data = coverage(filename, cov[filename]); + ret.files.push(data); + ret.hits += data.hits; + ret.misses += data.misses; + ret.sloc += data.sloc; + } + } + + ret.files.sort(function(a, b) { + return a.filename.localeCompare(b.filename); + }); + + if (ret.sloc > 0) { + ret.coverage = (ret.hits / ret.sloc) * 100; + } + + return ret; +} + +/** + * Map jscoverage data for a single source file + * to a JSON structure suitable for reporting. + * + * @api private + * @param {string} filename name of the source file + * @param {Object} data jscoverage coverage data + * @return {Object} + */ +function coverage(filename, data) { + var ret = { + filename: filename, + coverage: 0, + hits: 0, + misses: 0, + sloc: 0, + source: {} + }; + + data.source.forEach(function(line, num) { + num++; + + if (data[num] === 0) { + ret.misses++; + ret.sloc++; + } else if (data[num] !== undefined) { + ret.hits++; + ret.sloc++; + } + + ret.source[num] = { + source: line, + coverage: data[num] === undefined ? '' : data[num] + }; + }); + + ret.coverage = ret.hits / ret.sloc * 100; + + return ret; +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean(test) { + return { + duration: test.duration, + currentRetry: test.currentRetry(), + fullTitle: test.fullTitle(), + title: test.title + }; +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./base":17,"_process":58}],24:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `List`. + */ + +exports = module.exports = List; + +/** + * Initialize a new `List` test reporter. + * + * @api public + * @param {Runner} runner + */ +function List(runner) { + Base.call(this, runner); + + var self = this; + var total = runner.total; + + runner.on('start', function() { + console.log(JSON.stringify(['start', { total: total }])); + }); + + runner.on('pass', function(test) { + console.log(JSON.stringify(['pass', clean(test)])); + }); + + runner.on('fail', function(test, err) { + test = clean(test); + test.err = err.message; + test.stack = err.stack || null; + console.log(JSON.stringify(['fail', test])); + }); + + runner.on('end', function() { + process.stdout.write(JSON.stringify(['end', self.stats])); + }); +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean(test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + currentRetry: test.currentRetry() + }; +} + +}).call(this,require('_process')) +},{"./base":17,"_process":58}],25:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `JSON`. + */ + +exports = module.exports = JSONReporter; + +/** + * Initialize a new `JSON` reporter. + * + * @api public + * @param {Runner} runner + */ +function JSONReporter(runner) { + Base.call(this, runner); + + var self = this; + var tests = []; + var pending = []; + var failures = []; + var passes = []; + + runner.on('test end', function(test) { + tests.push(test); + }); + + runner.on('pass', function(test) { + passes.push(test); + }); + + runner.on('fail', function(test) { + failures.push(test); + }); + + runner.on('pending', function(test) { + pending.push(test); + }); + + runner.on('end', function() { + var obj = { + stats: self.stats, + tests: tests.map(clean), + pending: pending.map(clean), + failures: failures.map(clean), + passes: passes.map(clean) + }; + + runner.testResults = obj; + + process.stdout.write(JSON.stringify(obj, null, 2)); + }); +} + +/** + * Return a plain-object representation of `test` + * free of cyclic properties etc. + * + * @api private + * @param {Object} test + * @return {Object} + */ +function clean(test) { + return { + title: test.title, + fullTitle: test.fullTitle(), + duration: test.duration, + currentRetry: test.currentRetry(), + err: errorJSON(test.err || {}) + }; +} + +/** + * Transform `error` into a JSON object. + * + * @api private + * @param {Error} err + * @return {Object} + */ +function errorJSON(err) { + var res = {}; + Object.getOwnPropertyNames(err).forEach(function(key) { + res[key] = err[key]; + }, err); + return res; +} + +}).call(this,require('_process')) +},{"./base":17,"_process":58}],26:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var cursor = Base.cursor; +var color = Base.color; + +/** + * Expose `Landing`. + */ + +exports = module.exports = Landing; + +/** + * Airplane color. + */ + +Base.colors.plane = 0; + +/** + * Airplane crash color. + */ + +Base.colors['plane crash'] = 31; + +/** + * Runway color. + */ + +Base.colors.runway = 90; + +/** + * Initialize a new `Landing` reporter. + * + * @api public + * @param {Runner} runner + */ +function Landing(runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * .75 | 0; + var total = runner.total; + var stream = process.stdout; + var plane = color('plane', '✈'); + var crashed = -1; + var n = 0; + + function runway() { + var buf = Array(width).join('-'); + return ' ' + color('runway', buf); + } + + runner.on('start', function() { + stream.write('\n\n\n '); + cursor.hide(); + }); + + runner.on('test end', function(test) { + // check if the plane crashed + var col = crashed === -1 ? width * ++n / total | 0 : crashed; + + // show the crash + if (test.state === 'failed') { + plane = color('plane crash', '✈'); + crashed = col; + } + + // render landing strip + stream.write('\u001b[' + (width + 1) + 'D\u001b[2A'); + stream.write(runway()); + stream.write('\n '); + stream.write(color('runway', Array(col).join('⋅'))); + stream.write(plane); + stream.write(color('runway', Array(width - col).join('⋅') + '\n')); + stream.write(runway()); + stream.write('\u001b[0m'); + }); + + runner.on('end', function() { + cursor.show(); + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Landing, Base); + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],27:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `List`. + */ + +exports = module.exports = List; + +/** + * Initialize a new `List` test reporter. + * + * @api public + * @param {Runner} runner + */ +function List(runner) { + Base.call(this, runner); + + var self = this; + var n = 0; + + runner.on('start', function() { + console.log(); + }); + + runner.on('test', function(test) { + process.stdout.write(color('pass', ' ' + test.fullTitle() + ': ')); + }); + + runner.on('pending', function(test) { + var fmt = color('checkmark', ' -') + + color('pending', ' %s'); + console.log(fmt, test.fullTitle()); + }); + + runner.on('pass', function(test) { + var fmt = color('checkmark', ' ' + Base.symbols.dot) + + color('pass', ' %s: ') + + color(test.speed, '%dms'); + cursor.CR(); + console.log(fmt, test.fullTitle(), test.duration); + }); + + runner.on('fail', function(test) { + cursor.CR(); + console.log(color('fail', ' %d) %s'), ++n, test.fullTitle()); + }); + + runner.on('end', self.epilogue.bind(self)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(List, Base); + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],28:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); + +/** + * Constants + */ + +var SUITE_PREFIX = '$'; + +/** + * Expose `Markdown`. + */ + +exports = module.exports = Markdown; + +/** + * Initialize a new `Markdown` reporter. + * + * @api public + * @param {Runner} runner + */ +function Markdown(runner) { + Base.call(this, runner); + + var level = 0; + var buf = ''; + + function title(str) { + return Array(level).join('#') + ' ' + str; + } + + function mapTOC(suite, obj) { + var ret = obj; + var key = SUITE_PREFIX + suite.title; + + obj = obj[key] = obj[key] || { suite: suite }; + suite.suites.forEach(function(suite) { + mapTOC(suite, obj); + }); + + return ret; + } + + function stringifyTOC(obj, level) { + ++level; + var buf = ''; + var link; + for (var key in obj) { + if (key === 'suite') { + continue; + } + if (key !== SUITE_PREFIX) { + link = ' - [' + key.substring(1) + ']'; + link += '(#' + utils.slug(obj[key].suite.fullTitle()) + ')\n'; + buf += Array(level).join(' ') + link; + } + buf += stringifyTOC(obj[key], level); + } + return buf; + } + + function generateTOC(suite) { + var obj = mapTOC(suite, {}); + return stringifyTOC(obj, 0); + } + + generateTOC(runner.suite); + + runner.on('suite', function(suite) { + ++level; + var slug = utils.slug(suite.fullTitle()); + buf += '' + '\n'; + buf += title(suite.title) + '\n'; + }); + + runner.on('suite end', function() { + --level; + }); + + runner.on('pass', function(test) { + var code = utils.clean(test.body); + buf += test.title + '.\n'; + buf += '\n```js\n'; + buf += code + '\n'; + buf += '```\n\n'; + }); + + runner.on('end', function() { + process.stdout.write('# TOC\n'); + process.stdout.write(generateTOC(runner.suite)); + process.stdout.write(buf); + }); +} + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],29:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; + +/** + * Expose `Min`. + */ + +exports = module.exports = Min; + +/** + * Initialize a new `Min` minimal test reporter (best used with --watch). + * + * @api public + * @param {Runner} runner + */ +function Min(runner) { + Base.call(this, runner); + + runner.on('start', function() { + // clear screen + process.stdout.write('\u001b[2J'); + // set cursor position + process.stdout.write('\u001b[1;3H'); + }); + + runner.on('end', this.epilogue.bind(this)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Min, Base); + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],30:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; + +/** + * Expose `Dot`. + */ + +exports = module.exports = NyanCat; + +/** + * Initialize a new `Dot` matrix test reporter. + * + * @param {Runner} runner + * @api public + */ + +function NyanCat(runner) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * .75 | 0; + var nyanCatWidth = this.nyanCatWidth = 11; + + this.colorIndex = 0; + this.numberOfLines = 4; + this.rainbowColors = self.generateColors(); + this.scoreboardWidth = 5; + this.tick = 0; + this.trajectories = [[], [], [], []]; + this.trajectoryWidthMax = (width - nyanCatWidth); + + runner.on('start', function() { + Base.cursor.hide(); + self.draw(); + }); + + runner.on('pending', function() { + self.draw(); + }); + + runner.on('pass', function() { + self.draw(); + }); + + runner.on('fail', function() { + self.draw(); + }); + + runner.on('end', function() { + Base.cursor.show(); + for (var i = 0; i < self.numberOfLines; i++) { + write('\n'); + } + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(NyanCat, Base); + +/** + * Draw the nyan cat + * + * @api private + */ + +NyanCat.prototype.draw = function() { + this.appendRainbow(); + this.drawScoreboard(); + this.drawRainbow(); + this.drawNyanCat(); + this.tick = !this.tick; +}; + +/** + * Draw the "scoreboard" showing the number + * of passes, failures and pending tests. + * + * @api private + */ + +NyanCat.prototype.drawScoreboard = function() { + var stats = this.stats; + + function draw(type, n) { + write(' '); + write(Base.color(type, n)); + write('\n'); + } + + draw('green', stats.passes); + draw('fail', stats.failures); + draw('pending', stats.pending); + write('\n'); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Append the rainbow. + * + * @api private + */ + +NyanCat.prototype.appendRainbow = function() { + var segment = this.tick ? '_' : '-'; + var rainbowified = this.rainbowify(segment); + + for (var index = 0; index < this.numberOfLines; index++) { + var trajectory = this.trajectories[index]; + if (trajectory.length >= this.trajectoryWidthMax) { + trajectory.shift(); + } + trajectory.push(rainbowified); + } +}; + +/** + * Draw the rainbow. + * + * @api private + */ + +NyanCat.prototype.drawRainbow = function() { + var self = this; + + this.trajectories.forEach(function(line) { + write('\u001b[' + self.scoreboardWidth + 'C'); + write(line.join('')); + write('\n'); + }); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Draw the nyan cat + * + * @api private + */ +NyanCat.prototype.drawNyanCat = function() { + var self = this; + var startWidth = this.scoreboardWidth + this.trajectories[0].length; + var dist = '\u001b[' + startWidth + 'C'; + var padding = ''; + + write(dist); + write('_,------,'); + write('\n'); + + write(dist); + padding = self.tick ? ' ' : ' '; + write('_|' + padding + '/\\_/\\ '); + write('\n'); + + write(dist); + padding = self.tick ? '_' : '__'; + var tail = self.tick ? '~' : '^'; + write(tail + '|' + padding + this.face() + ' '); + write('\n'); + + write(dist); + padding = self.tick ? ' ' : ' '; + write(padding + '"" "" '); + write('\n'); + + this.cursorUp(this.numberOfLines); +}; + +/** + * Draw nyan cat face. + * + * @api private + * @return {string} + */ + +NyanCat.prototype.face = function() { + var stats = this.stats; + if (stats.failures) { + return '( x .x)'; + } else if (stats.pending) { + return '( o .o)'; + } else if (stats.passes) { + return '( ^ .^)'; + } + return '( - .-)'; +}; + +/** + * Move cursor up `n`. + * + * @api private + * @param {number} n + */ + +NyanCat.prototype.cursorUp = function(n) { + write('\u001b[' + n + 'A'); +}; + +/** + * Move cursor down `n`. + * + * @api private + * @param {number} n + */ + +NyanCat.prototype.cursorDown = function(n) { + write('\u001b[' + n + 'B'); +}; + +/** + * Generate rainbow colors. + * + * @api private + * @return {Array} + */ +NyanCat.prototype.generateColors = function() { + var colors = []; + + for (var i = 0; i < (6 * 7); i++) { + var pi3 = Math.floor(Math.PI / 3); + var n = (i * (1.0 / 6)); + var r = Math.floor(3 * Math.sin(n) + 3); + var g = Math.floor(3 * Math.sin(n + 2 * pi3) + 3); + var b = Math.floor(3 * Math.sin(n + 4 * pi3) + 3); + colors.push(36 * r + 6 * g + b + 16); + } + + return colors; +}; + +/** + * Apply rainbow to the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +NyanCat.prototype.rainbowify = function(str) { + if (!Base.useColors) { + return str; + } + var color = this.rainbowColors[this.colorIndex % this.rainbowColors.length]; + this.colorIndex += 1; + return '\u001b[38;5;' + color + 'm' + str + '\u001b[0m'; +}; + +/** + * Stdout helper. + * + * @param {string} string A message to write to stdout. + */ +function write(string) { + process.stdout.write(string); +} + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],31:[function(require,module,exports){ +(function (process){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `Progress`. + */ + +exports = module.exports = Progress; + +/** + * General progress bar color. + */ + +Base.colors.progress = 90; + +/** + * Initialize a new `Progress` bar test reporter. + * + * @api public + * @param {Runner} runner + * @param {Object} options + */ +function Progress(runner, options) { + Base.call(this, runner); + + var self = this; + var width = Base.window.width * .50 | 0; + var total = runner.total; + var complete = 0; + var lastN = -1; + + // default chars + options = options || {}; + options.open = options.open || '['; + options.complete = options.complete || '▬'; + options.incomplete = options.incomplete || Base.symbols.dot; + options.close = options.close || ']'; + options.verbose = false; + + // tests started + runner.on('start', function() { + console.log(); + cursor.hide(); + }); + + // tests complete + runner.on('test end', function() { + complete++; + + var percent = complete / total; + var n = width * percent | 0; + var i = width - n; + + if (n === lastN && !options.verbose) { + // Don't re-render the line if it hasn't changed + return; + } + lastN = n; + + cursor.CR(); + process.stdout.write('\u001b[J'); + process.stdout.write(color('progress', ' ' + options.open)); + process.stdout.write(Array(n).join(options.complete)); + process.stdout.write(Array(i).join(options.incomplete)); + process.stdout.write(color('progress', options.close)); + if (options.verbose) { + process.stdout.write(color('progress', ' ' + complete + ' of ' + total)); + } + }); + + // tests are complete, output some stats + // and the failures if any + runner.on('end', function() { + cursor.show(); + console.log(); + self.epilogue(); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Progress, Base); + +}).call(this,require('_process')) +},{"../utils":39,"./base":17,"_process":58}],32:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var inherits = require('../utils').inherits; +var color = Base.color; +var cursor = Base.cursor; + +/** + * Expose `Spec`. + */ + +exports = module.exports = Spec; + +/** + * Initialize a new `Spec` test reporter. + * + * @api public + * @param {Runner} runner + */ +function Spec(runner) { + Base.call(this, runner); + + var self = this; + var indents = 0; + var n = 0; + + function indent() { + return Array(indents).join(' '); + } + + runner.on('start', function() { + console.log(); + }); + + runner.on('suite', function(suite) { + ++indents; + console.log(color('suite', '%s%s'), indent(), suite.title); + }); + + runner.on('suite end', function() { + --indents; + if (indents === 1) { + console.log(); + } + }); + + runner.on('pending', function(test) { + var fmt = indent() + color('pending', ' - %s'); + console.log(fmt, test.title); + }); + + runner.on('pass', function(test) { + var fmt; + if (test.speed === 'fast') { + fmt = indent() + + color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s'); + cursor.CR(); + console.log(fmt, test.title); + } else { + fmt = indent() + + color('checkmark', ' ' + Base.symbols.ok) + + color('pass', ' %s') + + color(test.speed, ' (%dms)'); + cursor.CR(); + console.log(fmt, test.title, test.duration); + } + }); + + runner.on('fail', function(test) { + cursor.CR(); + console.log(indent() + color('fail', ' %d) %s'), ++n, test.title); + }); + + runner.on('end', self.epilogue.bind(self)); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(Spec, Base); + +},{"../utils":39,"./base":17}],33:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Base = require('./base'); + +/** + * Expose `TAP`. + */ + +exports = module.exports = TAP; + +/** + * Initialize a new `TAP` reporter. + * + * @api public + * @param {Runner} runner + */ +function TAP(runner) { + Base.call(this, runner); + + var n = 1; + var passes = 0; + var failures = 0; + + runner.on('start', function() { + var total = runner.grepTotal(runner.suite); + console.log('%d..%d', 1, total); + }); + + runner.on('test end', function() { + ++n; + }); + + runner.on('pending', function(test) { + console.log('ok %d %s # SKIP -', n, title(test)); + }); + + runner.on('pass', function(test) { + passes++; + console.log('ok %d %s', n, title(test)); + }); + + runner.on('fail', function(test, err) { + failures++; + console.log('not ok %d %s', n, title(test)); + if (err.stack) { + console.log(err.stack.replace(/^/gm, ' ')); + } + }); + + runner.on('end', function() { + console.log('# tests ' + (passes + failures)); + console.log('# pass ' + passes); + console.log('# fail ' + failures); + }); +} + +/** + * Return a TAP-safe title of `test` + * + * @api private + * @param {Object} test + * @return {String} + */ +function title(test) { + return test.fullTitle().replace(/#/g, ''); +} + +},{"./base":17}],34:[function(require,module,exports){ +(function (process,global){ +/** + * Module dependencies. + */ + +var Base = require('./base'); +var utils = require('../utils'); +var inherits = utils.inherits; +var fs = require('fs'); +var escape = utils.escape; +var mkdirp = require('mkdirp'); +var path = require('path'); + +/** + * Save timer references to avoid Sinon interfering (see GH-237). + */ + +/* eslint-disable no-unused-vars, no-native-reassign */ +var Date = global.Date; +var setTimeout = global.setTimeout; +var setInterval = global.setInterval; +var clearTimeout = global.clearTimeout; +var clearInterval = global.clearInterval; +/* eslint-enable no-unused-vars, no-native-reassign */ + +/** + * Expose `XUnit`. + */ + +exports = module.exports = XUnit; + +/** + * Initialize a new `XUnit` reporter. + * + * @api public + * @param {Runner} runner + */ +function XUnit(runner, options) { + Base.call(this, runner); + + var stats = this.stats; + var tests = []; + var self = this; + + if (options.reporterOptions && options.reporterOptions.output) { + if (!fs.createWriteStream) { + throw new Error('file output not supported in browser'); + } + mkdirp.sync(path.dirname(options.reporterOptions.output)); + self.fileStream = fs.createWriteStream(options.reporterOptions.output); + } + + runner.on('pending', function(test) { + tests.push(test); + }); + + runner.on('pass', function(test) { + tests.push(test); + }); + + runner.on('fail', function(test) { + tests.push(test); + }); + + runner.on('end', function() { + self.write(tag('testsuite', { + name: 'Mocha Tests', + tests: stats.tests, + failures: stats.failures, + errors: stats.failures, + skipped: stats.tests - stats.failures - stats.passes, + timestamp: (new Date()).toUTCString(), + time: (stats.duration / 1000) || 0 + }, false)); + + tests.forEach(function(t) { + self.test(t); + }); + + self.write(''); + }); +} + +/** + * Inherit from `Base.prototype`. + */ +inherits(XUnit, Base); + +/** + * Override done to close the stream (if it's a file). + * + * @param failures + * @param {Function} fn + */ +XUnit.prototype.done = function(failures, fn) { + if (this.fileStream) { + this.fileStream.end(function() { + fn(failures); + }); + } else { + fn(failures); + } +}; + +/** + * Write out the given line. + * + * @param {string} line + */ +XUnit.prototype.write = function(line) { + if (this.fileStream) { + this.fileStream.write(line + '\n'); + } else if (typeof process === 'object' && process.stdout) { + process.stdout.write(line + '\n'); + } else { + console.log(line); + } +}; + +/** + * Output tag for the given `test.` + * + * @param {Test} test + */ +XUnit.prototype.test = function(test) { + var attrs = { + classname: test.parent.fullTitle(), + name: test.title, + time: (test.duration / 1000) || 0 + }; + + if (test.state === 'failed') { + var err = test.err; + this.write(tag('testcase', attrs, false, tag('failure', {}, false, escape(err.message) + '\n' + escape(err.stack)))); + } else if (test.isPending()) { + this.write(tag('testcase', attrs, false, tag('skipped', {}, true))); + } else { + this.write(tag('testcase', attrs, true)); + } +}; + +/** + * HTML tag helper. + * + * @param name + * @param attrs + * @param close + * @param content + * @return {string} + */ +function tag(name, attrs, close, content) { + var end = close ? '/>' : '>'; + var pairs = []; + var tag; + + for (var key in attrs) { + if (Object.prototype.hasOwnProperty.call(attrs, key)) { + pairs.push(key + '="' + escape(attrs[key]) + '"'); + } + } + + tag = '<' + name + (pairs.length ? ' ' + pairs.join(' ') : '') + end; + if (content) { + tag += content + ''; + } + if (key === 'ctx') { + return '#'; + } + return val; + }, 2); +}; + +/** + * Reset the timeout. + * + * @api private + */ +Runnable.prototype.resetTimeout = function() { + var self = this; + var ms = this.timeout() || 1e9; + + if (!this._enableTimeouts) { + return; + } + this.clearTimeout(); + this.timer = setTimeout(function() { + if (!self._enableTimeouts) { + return; + } + self.callback(new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.')); + self.timedOut = true; + }, ms); +}; + +/** + * Whitelist a list of globals for this test run. + * + * @api private + * @param {string[]} globals + */ +Runnable.prototype.globals = function(globals) { + if (!arguments.length) { + return this._allowedGlobals; + } + this._allowedGlobals = globals; +}; + +/** + * Run the test and invoke `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runnable.prototype.run = function(fn) { + var self = this; + var start = new Date(); + var ctx = this.ctx; + var finished; + var emitted; + + // Sometimes the ctx exists, but it is not runnable + if (ctx && ctx.runnable) { + ctx.runnable(this); + } + + // called multiple times + function multiple(err) { + if (emitted) { + return; + } + emitted = true; + self.emit('error', err || new Error('done() called multiple times; stacktrace may be inaccurate')); + } + + // finished + function done(err) { + var ms = self.timeout(); + if (self.timedOut) { + return; + } + if (finished) { + return multiple(err || self._trace); + } + + self.clearTimeout(); + self.duration = new Date() - start; + finished = true; + if (!err && self.duration > ms && self._enableTimeouts) { + err = new Error('timeout of ' + ms + 'ms exceeded. Ensure the done() callback is being called in this test.'); + } + fn(err); + } + + // for .resetTimeout() + this.callback = done; + + // explicit async with `done` argument + if (this.async) { + this.resetTimeout(); + + if (this.allowUncaught) { + return callFnAsync(this.fn); + } + try { + callFnAsync(this.fn); + } catch (err) { + done(utils.getError(err)); + } + return; + } + + if (this.allowUncaught) { + callFn(this.fn); + done(); + return; + } + + // sync or promise-returning + try { + if (this.isPending()) { + done(); + } else { + callFn(this.fn); + } + } catch (err) { + done(utils.getError(err)); + } + + function callFn(fn) { + var result = fn.call(ctx); + if (result && typeof result.then === 'function') { + self.resetTimeout(); + result + .then(function() { + done(); + // Return null so libraries like bluebird do not warn about + // subsequently constructed Promises. + return null; + }, + function(reason) { + done(reason || new Error('Promise rejected with no or falsy reason')); + }); + } else { + if (self.asyncOnly) { + return done(new Error('--async-only option in use without declaring `done()` or returning a promise')); + } + + done(); + } + } + + function callFnAsync(fn) { + fn.call(ctx, function(err) { + if (err instanceof Error || toString.call(err) === '[object Error]') { + return done(err); + } + if (err) { + if (Object.prototype.toString.call(err) === '[object Object]') { + return done(new Error('done() invoked with non-Error: ' + + JSON.stringify(err))); + } + return done(new Error('done() invoked with non-Error: ' + err)); + } + done(); + }); + } +}; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./ms":15,"./pending":16,"./utils":39,"debug":2,"events":3}],36:[function(require,module,exports){ +(function (process,global){ +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Pending = require('./pending'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:runner'); +var Runnable = require('./runnable'); +var filter = utils.filter; +var indexOf = utils.indexOf; +var keys = utils.keys; +var stackFilter = utils.stackTraceFilter(); +var stringify = utils.stringify; +var type = utils.type; +var undefinedError = utils.undefinedError; +var isArray = utils.isArray; + +/** + * Non-enumerable globals. + */ + +var globals = [ + 'setTimeout', + 'clearTimeout', + 'setInterval', + 'clearInterval', + 'XMLHttpRequest', + 'Date', + 'setImmediate', + 'clearImmediate' +]; + +/** + * Expose `Runner`. + */ + +module.exports = Runner; + +/** + * Initialize a `Runner` for the given `suite`. + * + * Events: + * + * - `start` execution started + * - `end` execution complete + * - `suite` (suite) test suite execution started + * - `suite end` (suite) all tests (and sub-suites) have finished + * - `test` (test) test execution started + * - `test end` (test) test completed + * - `hook` (hook) hook execution started + * - `hook end` (hook) hook complete + * - `pass` (test) test passed + * - `fail` (test, err) test failed + * - `pending` (test) test pending + * + * @api public + * @param {Suite} suite Root suite + * @param {boolean} [delay] Whether or not to delay execution of root suite + * until ready. + */ +function Runner(suite, delay) { + var self = this; + this._globals = []; + this._abort = false; + this._delay = delay; + this.suite = suite; + this.started = false; + this.total = suite.total(); + this.failures = 0; + this.on('test end', function(test) { + self.checkGlobals(test); + }); + this.on('hook end', function(hook) { + self.checkGlobals(hook); + }); + this._defaultGrep = /.*/; + this.grep(this._defaultGrep); + this.globals(this.globalProps().concat(extraGlobals())); +} + +/** + * Wrapper for setImmediate, process.nextTick, or browser polyfill. + * + * @param {Function} fn + * @api private + */ +Runner.immediately = global.setImmediate || process.nextTick; + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Runner, EventEmitter); + +/** + * Run tests with full titles matching `re`. Updates runner.total + * with number of tests matched. + * + * @param {RegExp} re + * @param {Boolean} invert + * @return {Runner} for chaining + * @api public + * @param {RegExp} re + * @param {boolean} invert + * @return {Runner} Runner instance. + */ +Runner.prototype.grep = function(re, invert) { + debug('grep %s', re); + this._grep = re; + this._invert = invert; + this.total = this.grepTotal(this.suite); + return this; +}; + +/** + * Returns the number of tests matching the grep search for the + * given suite. + * + * @param {Suite} suite + * @return {Number} + * @api public + * @param {Suite} suite + * @return {number} + */ +Runner.prototype.grepTotal = function(suite) { + var self = this; + var total = 0; + + suite.eachTest(function(test) { + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (match) { + total++; + } + }); + + return total; +}; + +/** + * Return a list of global properties. + * + * @return {Array} + * @api private + */ +Runner.prototype.globalProps = function() { + var props = keys(global); + + // non-enumerables + for (var i = 0; i < globals.length; ++i) { + if (~indexOf(props, globals[i])) { + continue; + } + props.push(globals[i]); + } + + return props; +}; + +/** + * Allow the given `arr` of globals. + * + * @param {Array} arr + * @return {Runner} for chaining + * @api public + * @param {Array} arr + * @return {Runner} Runner instance. + */ +Runner.prototype.globals = function(arr) { + if (!arguments.length) { + return this._globals; + } + debug('globals %j', arr); + this._globals = this._globals.concat(arr); + return this; +}; + +/** + * Check for global variable leaks. + * + * @api private + */ +Runner.prototype.checkGlobals = function(test) { + if (this.ignoreLeaks) { + return; + } + var ok = this._globals; + + var globals = this.globalProps(); + var leaks; + + if (test) { + ok = ok.concat(test._allowedGlobals || []); + } + + if (this.prevGlobalsLength === globals.length) { + return; + } + this.prevGlobalsLength = globals.length; + + leaks = filterLeaks(ok, globals); + this._globals = this._globals.concat(leaks); + + if (leaks.length > 1) { + this.fail(test, new Error('global leaks detected: ' + leaks.join(', ') + '')); + } else if (leaks.length) { + this.fail(test, new Error('global leak detected: ' + leaks[0])); + } +}; + +/** + * Fail the given `test`. + * + * @api private + * @param {Test} test + * @param {Error} err + */ +Runner.prototype.fail = function(test, err) { + ++this.failures; + test.state = 'failed'; + + if (!(err instanceof Error || err && typeof err.message === 'string')) { + err = new Error('the ' + type(err) + ' ' + stringify(err) + ' was thrown, throw an Error :)'); + } + + err.stack = (this.fullStackTrace || !err.stack) + ? err.stack + : stackFilter(err.stack); + + this.emit('fail', test, err); +}; + +/** + * Fail the given `hook` with `err`. + * + * Hook failures work in the following pattern: + * - If bail, then exit + * - Failed `before` hook skips all tests in a suite and subsuites, + * but jumps to corresponding `after` hook + * - Failed `before each` hook skips remaining tests in a + * suite and jumps to corresponding `after each` hook, + * which is run only once + * - Failed `after` hook does not alter + * execution order + * - Failed `after each` hook skips remaining tests in a + * suite and subsuites, but executes other `after each` + * hooks + * + * @api private + * @param {Hook} hook + * @param {Error} err + */ +Runner.prototype.failHook = function(hook, err) { + if (hook.ctx && hook.ctx.currentTest) { + hook.originalTitle = hook.originalTitle || hook.title; + hook.title = hook.originalTitle + ' for "' + hook.ctx.currentTest.title + '"'; + } + + this.fail(hook, err); + if (this.suite.bail()) { + this.emit('end'); + } +}; + +/** + * Run hook `name` callbacks and then invoke `fn()`. + * + * @api private + * @param {string} name + * @param {Function} fn + */ + +Runner.prototype.hook = function(name, fn) { + var suite = this.suite; + var hooks = suite['_' + name]; + var self = this; + + function next(i) { + var hook = hooks[i]; + if (!hook) { + return fn(); + } + self.currentRunnable = hook; + + hook.ctx.currentTest = self.test; + + self.emit('hook', hook); + + if (!hook.listeners('error').length) { + hook.on('error', function(err) { + self.failHook(hook, err); + }); + } + + hook.run(function(err) { + var testError = hook.error(); + if (testError) { + self.fail(self.test, testError); + } + if (err) { + if (err instanceof Pending) { + suite.pending = true; + } else { + self.failHook(hook, err); + + // stop executing hooks, notify callee of hook err + return fn(err); + } + } + self.emit('hook end', hook); + delete hook.ctx.currentTest; + next(++i); + }); + } + + Runner.immediately(function() { + next(0); + }); +}; + +/** + * Run hook `name` for the given array of `suites` + * in order, and callback `fn(err, errSuite)`. + * + * @api private + * @param {string} name + * @param {Array} suites + * @param {Function} fn + */ +Runner.prototype.hooks = function(name, suites, fn) { + var self = this; + var orig = this.suite; + + function next(suite) { + self.suite = suite; + + if (!suite) { + self.suite = orig; + return fn(); + } + + self.hook(name, function(err) { + if (err) { + var errSuite = self.suite; + self.suite = orig; + return fn(err, errSuite); + } + + next(suites.pop()); + }); + } + + next(suites.pop()); +}; + +/** + * Run hooks from the top level down. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookUp = function(name, fn) { + var suites = [this.suite].concat(this.parents()).reverse(); + this.hooks(name, suites, fn); +}; + +/** + * Run hooks from the bottom up. + * + * @param {String} name + * @param {Function} fn + * @api private + */ +Runner.prototype.hookDown = function(name, fn) { + var suites = [this.suite].concat(this.parents()); + this.hooks(name, suites, fn); +}; + +/** + * Return an array of parent Suites from + * closest to furthest. + * + * @return {Array} + * @api private + */ +Runner.prototype.parents = function() { + var suite = this.suite; + var suites = []; + while (suite.parent) { + suite = suite.parent; + suites.push(suite); + } + return suites; +}; + +/** + * Run the current test and callback `fn(err)`. + * + * @param {Function} fn + * @api private + */ +Runner.prototype.runTest = function(fn) { + var self = this; + var test = this.test; + + if (this.asyncOnly) { + test.asyncOnly = true; + } + + if (this.allowUncaught) { + test.allowUncaught = true; + return test.run(fn); + } + try { + test.on('error', function(err) { + self.fail(test, err); + }); + test.run(fn); + } catch (err) { + fn(err); + } +}; + +/** + * Run tests in the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runTests = function(suite, fn) { + var self = this; + var tests = suite.tests.slice(); + var test; + + function hookErr(_, errSuite, after) { + // before/after Each hook for errSuite failed: + var orig = self.suite; + + // for failed 'after each' hook start from errSuite parent, + // otherwise start from errSuite itself + self.suite = after ? errSuite.parent : errSuite; + + if (self.suite) { + // call hookUp afterEach + self.hookUp('afterEach', function(err2, errSuite2) { + self.suite = orig; + // some hooks may fail even now + if (err2) { + return hookErr(err2, errSuite2, true); + } + // report error suite + fn(errSuite); + }); + } else { + // there is no need calling other 'after each' hooks + self.suite = orig; + fn(errSuite); + } + } + + function next(err, errSuite) { + // if we bail after first err + if (self.failures && suite._bail) { + return fn(); + } + + if (self._abort) { + return fn(); + } + + if (err) { + return hookErr(err, errSuite, true); + } + + // next test + test = tests.shift(); + + // all done + if (!test) { + return fn(); + } + + // grep + var match = self._grep.test(test.fullTitle()); + if (self._invert) { + match = !match; + } + if (!match) { + // Run immediately only if we have defined a grep. When we + // define a grep — It can cause maximum callstack error if + // the grep is doing a large recursive loop by neglecting + // all tests. The run immediately function also comes with + // a performance cost. So we don't want to run immediately + // if we run the whole test suite, because running the whole + // test suite don't do any immediate recursive loops. Thus, + // allowing a JS runtime to breathe. + if (self._grep !== self._defaultGrep) { + Runner.immediately(next); + } else { + next(); + } + return; + } + + if (test.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + + // execute test and hook(s) + self.emit('test', self.test = test); + self.hookDown('beforeEach', function(err, errSuite) { + if (suite.isPending()) { + self.emit('pending', test); + self.emit('test end', test); + return next(); + } + if (err) { + return hookErr(err, errSuite, false); + } + self.currentRunnable = self.test; + self.runTest(function(err) { + test = self.test; + if (err) { + var retry = test.currentRetry(); + if (err instanceof Pending) { + test.pending = true; + self.emit('pending', test); + } else if (retry < test.retries()) { + var clonedTest = test.clone(); + clonedTest.currentRetry(retry + 1); + tests.unshift(clonedTest); + + // Early return + hook trigger so that it doesn't + // increment the count wrong + return self.hookUp('afterEach', next); + } else { + self.fail(test, err); + } + self.emit('test end', test); + + if (err instanceof Pending) { + return next(); + } + + return self.hookUp('afterEach', next); + } + + test.state = 'passed'; + self.emit('pass', test); + self.emit('test end', test); + self.hookUp('afterEach', next); + }); + }); + } + + this.next = next; + this.hookErr = hookErr; + next(); +}; + +/** + * Run the given `suite` and invoke the callback `fn()` when complete. + * + * @api private + * @param {Suite} suite + * @param {Function} fn + */ +Runner.prototype.runSuite = function(suite, fn) { + var i = 0; + var self = this; + var total = this.grepTotal(suite); + var afterAllHookCalled = false; + + debug('run suite %s', suite.fullTitle()); + + if (!total || (self.failures && suite._bail)) { + return fn(); + } + + this.emit('suite', this.suite = suite); + + function next(errSuite) { + if (errSuite) { + // current suite failed on a hook from errSuite + if (errSuite === suite) { + // if errSuite is current suite + // continue to the next sibling suite + return done(); + } + // errSuite is among the parents of current suite + // stop execution of errSuite and all sub-suites + return done(errSuite); + } + + if (self._abort) { + return done(); + } + + var curr = suite.suites[i++]; + if (!curr) { + return done(); + } + + // Avoid grep neglecting large number of tests causing a + // huge recursive loop and thus a maximum call stack error. + // See comment in `this.runTests()` for more information. + if (self._grep !== self._defaultGrep) { + Runner.immediately(function() { + self.runSuite(curr, next); + }); + } else { + self.runSuite(curr, next); + } + } + + function done(errSuite) { + self.suite = suite; + self.nextSuite = next; + + if (afterAllHookCalled) { + fn(errSuite); + } else { + // mark that the afterAll block has been called once + // and so can be skipped if there is an error in it. + afterAllHookCalled = true; + + // remove reference to test + delete self.test; + + self.hook('afterAll', function() { + self.emit('suite end', suite); + fn(errSuite); + }); + } + } + + this.nextSuite = next; + + this.hook('beforeAll', function(err) { + if (err) { + return done(); + } + self.runTests(suite, next); + }); +}; + +/** + * Handle uncaught exceptions. + * + * @param {Error} err + * @api private + */ +Runner.prototype.uncaught = function(err) { + if (err) { + debug('uncaught exception %s', err !== function() { + return this; + }.call(err) ? err : (err.message || err)); + } else { + debug('uncaught undefined exception'); + err = undefinedError(); + } + err.uncaught = true; + + var runnable = this.currentRunnable; + + if (!runnable) { + runnable = new Runnable('Uncaught error outside test suite'); + runnable.parent = this.suite; + + if (this.started) { + this.fail(runnable, err); + } else { + // Can't recover from this failure + this.emit('start'); + this.fail(runnable, err); + this.emit('end'); + } + + return; + } + + runnable.clearTimeout(); + + // Ignore errors if complete + if (runnable.state) { + return; + } + this.fail(runnable, err); + + // recover from test + if (runnable.type === 'test') { + this.emit('test end', runnable); + this.hookUp('afterEach', this.next); + return; + } + + // recover from hooks + if (runnable.type === 'hook') { + var errSuite = this.suite; + // if hook failure is in afterEach block + if (runnable.fullTitle().indexOf('after each') > -1) { + return this.hookErr(err, errSuite, true); + } + // if hook failure is in beforeEach block + if (runnable.fullTitle().indexOf('before each') > -1) { + return this.hookErr(err, errSuite, false); + } + // if hook failure is in after or before blocks + return this.nextSuite(errSuite); + } + + // bail + this.emit('end'); +}; + +/** + * Cleans up the references to all the deferred functions + * (before/after/beforeEach/afterEach) and tests of a Suite. + * These must be deleted otherwise a memory leak can happen, + * as those functions may reference variables from closures, + * thus those variables can never be garbage collected as long + * as the deferred functions exist. + * + * @param {Suite} suite + */ +function cleanSuiteReferences(suite) { + function cleanArrReferences(arr) { + for (var i = 0; i < arr.length; i++) { + delete arr[i].fn; + } + } + + if (isArray(suite._beforeAll)) { + cleanArrReferences(suite._beforeAll); + } + + if (isArray(suite._beforeEach)) { + cleanArrReferences(suite._beforeEach); + } + + if (isArray(suite._afterAll)) { + cleanArrReferences(suite._afterAll); + } + + if (isArray(suite._afterEach)) { + cleanArrReferences(suite._afterEach); + } + + for (var i = 0; i < suite.tests.length; i++) { + delete suite.tests[i].fn; + } +} + +/** + * Run the root suite and invoke `fn(failures)` + * on completion. + * + * @param {Function} fn + * @return {Runner} for chaining + * @api public + * @param {Function} fn + * @return {Runner} Runner instance. + */ +Runner.prototype.run = function(fn) { + var self = this; + var rootSuite = this.suite; + + fn = fn || function() {}; + + function uncaught(err) { + self.uncaught(err); + } + + function start() { + self.started = true; + self.emit('start'); + self.runSuite(rootSuite, function() { + debug('finished running'); + self.emit('end'); + }); + } + + debug('start'); + + // references cleanup to avoid memory leaks + this.on('suite end', cleanSuiteReferences); + + // callback + this.on('end', function() { + debug('end'); + process.removeListener('uncaughtException', uncaught); + fn(self.failures); + }); + + // uncaught exception + process.on('uncaughtException', uncaught); + + if (this._delay) { + // for reporters, I guess. + // might be nice to debounce some dots while we wait. + this.emit('waiting', rootSuite); + rootSuite.once('run', start); + } else { + start(); + } + + return this; +}; + +/** + * Cleanly abort execution. + * + * @api public + * @return {Runner} Runner instance. + */ +Runner.prototype.abort = function() { + debug('aborting'); + this._abort = true; + + return this; +}; + +/** + * Filter leaks with the given globals flagged as `ok`. + * + * @api private + * @param {Array} ok + * @param {Array} globals + * @return {Array} + */ +function filterLeaks(ok, globals) { + return filter(globals, function(key) { + // Firefox and Chrome exposes iframes as index inside the window object + if (/^d+/.test(key)) { + return false; + } + + // in firefox + // if runner runs in an iframe, this iframe's window.getInterface method not init at first + // it is assigned in some seconds + if (global.navigator && (/^getInterface/).test(key)) { + return false; + } + + // an iframe could be approached by window[iframeIndex] + // in ie6,7,8 and opera, iframeIndex is enumerable, this could cause leak + if (global.navigator && (/^\d+/).test(key)) { + return false; + } + + // Opera and IE expose global variables for HTML element IDs (issue #243) + if (/^mocha-/.test(key)) { + return false; + } + + var matched = filter(ok, function(ok) { + if (~ok.indexOf('*')) { + return key.indexOf(ok.split('*')[0]) === 0; + } + return key === ok; + }); + return !matched.length && (!global.navigator || key !== 'onerror'); + }); +} + +/** + * Array of globals dependent on the environment. + * + * @return {Array} + * @api private + */ +function extraGlobals() { + if (typeof process === 'object' && typeof process.version === 'string') { + var parts = process.version.split('.'); + var nodeVersion = utils.reduce(parts, function(a, v) { + return a << 8 | v; + }); + + // 'errno' was renamed to process._errno in v0.9.11. + + if (nodeVersion < 0x00090B) { + return ['errno']; + } + } + + return []; +} + +}).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./pending":16,"./runnable":35,"./utils":39,"_process":58,"debug":2,"events":3}],37:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var Hook = require('./hook'); +var utils = require('./utils'); +var inherits = utils.inherits; +var debug = require('debug')('mocha:suite'); +var milliseconds = require('./ms'); + +/** + * Expose `Suite`. + */ + +exports = module.exports = Suite; + +/** + * Create a new `Suite` with the given `title` and parent `Suite`. When a suite + * with the same title is already present, that suite is returned to provide + * nicer reporter and more flexible meta-testing. + * + * @api public + * @param {Suite} parent + * @param {string} title + * @return {Suite} + */ +exports.create = function(parent, title) { + var suite = new Suite(title, parent.ctx); + suite.parent = parent; + title = suite.fullTitle(); + parent.addSuite(suite); + return suite; +}; + +/** + * Initialize a new `Suite` with the given `title` and `ctx`. + * + * @api private + * @param {string} title + * @param {Context} parentContext + */ +function Suite(title, parentContext) { + this.title = title; + function Context() {} + Context.prototype = parentContext; + this.ctx = new Context(); + this.suites = []; + this.tests = []; + this.pending = false; + this._beforeEach = []; + this._beforeAll = []; + this._afterEach = []; + this._afterAll = []; + this.root = !title; + this._timeout = 2000; + this._enableTimeouts = true; + this._slow = 75; + this._bail = false; + this._retries = -1; + this.delayed = false; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ +inherits(Suite, EventEmitter); + +/** + * Return a clone of this `Suite`. + * + * @api private + * @return {Suite} + */ +Suite.prototype.clone = function() { + var suite = new Suite(this.title); + debug('clone'); + suite.ctx = this.ctx; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + return suite; +}; + +/** + * Set timeout `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.timeout = function(ms) { + if (!arguments.length) { + return this._timeout; + } + if (ms.toString() === '0') { + this._enableTimeouts = false; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('timeout %d', ms); + this._timeout = parseInt(ms, 10); + return this; +}; + +/** + * Set number of times to retry a failed test. + * + * @api private + * @param {number|string} n + * @return {Suite|number} for chaining + */ +Suite.prototype.retries = function(n) { + if (!arguments.length) { + return this._retries; + } + debug('retries %d', n); + this._retries = parseInt(n, 10) || 0; + return this; +}; + +/** + * Set timeout to `enabled`. + * + * @api private + * @param {boolean} enabled + * @return {Suite|boolean} self or enabled + */ +Suite.prototype.enableTimeouts = function(enabled) { + if (!arguments.length) { + return this._enableTimeouts; + } + debug('enableTimeouts %s', enabled); + this._enableTimeouts = enabled; + return this; +}; + +/** + * Set slow `ms` or short-hand such as "2s". + * + * @api private + * @param {number|string} ms + * @return {Suite|number} for chaining + */ +Suite.prototype.slow = function(ms) { + if (!arguments.length) { + return this._slow; + } + if (typeof ms === 'string') { + ms = milliseconds(ms); + } + debug('slow %d', ms); + this._slow = ms; + return this; +}; + +/** + * Sets whether to bail after first error. + * + * @api private + * @param {boolean} bail + * @return {Suite|number} for chaining + */ +Suite.prototype.bail = function(bail) { + if (!arguments.length) { + return this._bail; + } + debug('bail %s', bail); + this._bail = 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. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeAll = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeAll.push(hook); + this.emit('beforeAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after running tests. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterAll = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after all" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterAll.push(hook); + this.emit('afterAll', hook); + return this; +}; + +/** + * Run `fn(test[, done])` before each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.beforeEach = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"before each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._beforeEach.push(hook); + this.emit('beforeEach', hook); + return this; +}; + +/** + * Run `fn(test[, done])` after each test case. + * + * @api private + * @param {string} title + * @param {Function} fn + * @return {Suite} for chaining + */ +Suite.prototype.afterEach = function(title, fn) { + if (this.isPending()) { + return this; + } + if (typeof title === 'function') { + fn = title; + title = fn.name; + } + title = '"after each" hook' + (title ? ': ' + title : ''); + + var hook = new Hook(title, fn); + hook.parent = this; + hook.timeout(this.timeout()); + hook.retries(this.retries()); + hook.enableTimeouts(this.enableTimeouts()); + hook.slow(this.slow()); + hook.ctx = this.ctx; + this._afterEach.push(hook); + this.emit('afterEach', hook); + return this; +}; + +/** + * Add a test `suite`. + * + * @api private + * @param {Suite} suite + * @return {Suite} for chaining + */ +Suite.prototype.addSuite = function(suite) { + suite.parent = this; + suite.timeout(this.timeout()); + suite.retries(this.retries()); + suite.enableTimeouts(this.enableTimeouts()); + suite.slow(this.slow()); + suite.bail(this.bail()); + this.suites.push(suite); + this.emit('suite', suite); + return this; +}; + +/** + * Add a `test` to this suite. + * + * @api private + * @param {Test} test + * @return {Suite} for chaining + */ +Suite.prototype.addTest = function(test) { + test.parent = this; + test.timeout(this.timeout()); + test.retries(this.retries()); + test.enableTimeouts(this.enableTimeouts()); + test.slow(this.slow()); + test.ctx = this.ctx; + this.tests.push(test); + this.emit('test', test); + return this; +}; + +/** + * Return the full title generated by recursively concatenating the parent's + * full title. + * + * @api public + * @return {string} + */ +Suite.prototype.fullTitle = function() { + if (this.parent) { + var full = this.parent.fullTitle(); + if (full) { + return full + ' ' + this.title; + } + } + return this.title; +}; + +/** + * Return the total number of tests. + * + * @api public + * @return {number} + */ +Suite.prototype.total = function() { + return utils.reduce(this.suites, function(sum, suite) { + return sum + suite.total(); + }, 0) + this.tests.length; +}; + +/** + * Iterates through each suite recursively to find all tests. Applies a + * function in the format `fn(test)`. + * + * @api private + * @param {Function} fn + * @return {Suite} + */ +Suite.prototype.eachTest = function(fn) { + utils.forEach(this.tests, fn); + utils.forEach(this.suites, function(suite) { + suite.eachTest(fn); + }); + return this; +}; + +/** + * This will run the root suite if we happen to be running in delayed mode. + */ +Suite.prototype.run = function run() { + if (this.root) { + this.emit('run'); + } +}; + +},{"./hook":7,"./ms":15,"./utils":39,"debug":2,"events":3}],38:[function(require,module,exports){ +/** + * Module dependencies. + */ + +var Runnable = require('./runnable'); +var inherits = require('./utils').inherits; + +/** + * Expose `Test`. + */ + +module.exports = Test; + +/** + * Initialize a new `Test` with the given `title` and callback `fn`. + * + * @api private + * @param {String} title + * @param {Function} fn + */ +function Test(title, fn) { + Runnable.call(this, title, fn); + this.pending = !fn; + this.type = 'test'; +} + +/** + * Inherit from `Runnable.prototype`. + */ +inherits(Test, Runnable); + +Test.prototype.clone = function() { + var test = new Test(this.title, this.fn); + test.timeout(this.timeout()); + test.slow(this.slow()); + test.enableTimeouts(this.enableTimeouts()); + test.retries(this.retries()); + test.currentRetry(this.currentRetry()); + test.globals(this.globals()); + test.parent = this.parent; + test.file = this.file; + test.ctx = this.ctx; + return test; +}; + +},{"./runnable":35,"./utils":39}],39:[function(require,module,exports){ +(function (process,Buffer){ +/* eslint-env browser */ + +/** + * Module dependencies. + */ + +var basename = require('path').basename; +var debug = require('debug')('mocha:watch'); +var exists = require('fs').existsSync || require('path').existsSync; +var glob = require('glob'); +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. + */ + +var ignore = ['node_modules', '.git']; + +exports.inherits = require('util').inherits; + +/** + * Escape special characters in the given string of html. + * + * @api private + * @param {string} html + * @return {string} + */ +exports.escape = function(html) { + return String(html) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(//g, '>'); +}; + +/** + * Array#forEach (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + */ +exports.forEach = function(arr, fn, scope) { + for (var i = 0, l = arr.length; i < l; i++) { + fn.call(scope, arr[i], i); + } +}; + +/** + * Test if the given obj is type of string. + * + * @api private + * @param {Object} obj + * @return {boolean} + */ +exports.isString = function(obj) { + return typeof obj === 'string'; +}; + +/** + * Array#map (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} scope + * @return {Array} + */ +exports.map = function(arr, fn, scope) { + var result = []; + for (var i = 0, l = arr.length; i < l; i++) { + result.push(fn.call(scope, arr[i], i, arr)); + } + return result; +}; + +/** + * Array#indexOf (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Object} obj to find index of + * @param {number} start + * @return {number} + */ +exports.indexOf = function(arr, obj, start) { + for (var i = start || 0, l = arr.length; i < l; i++) { + if (arr[i] === obj) { + return i; + } + } + return -1; +}; + +/** + * Array#reduce (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @param {Object} val Initial value. + * @return {*} + */ +exports.reduce = function(arr, fn, val) { + var rval = val; + + for (var i = 0, l = arr.length; i < l; i++) { + rval = fn(rval, arr[i], i, arr); + } + + return rval; +}; + +/** + * Array#filter (<=IE8) + * + * @api private + * @param {Array} arr + * @param {Function} fn + * @return {Array} + */ +exports.filter = function(arr, fn) { + var ret = []; + + for (var i = 0, l = arr.length; i < l; i++) { + var val = arr[i]; + if (fn(val, i, arr)) { + ret.push(val); + } + } + + return ret; +}; + +/** + * Object.keys (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Array} keys + */ +exports.keys = typeof Object.keys === 'function' ? Object.keys : function(obj) { + var keys = []; + var has = Object.prototype.hasOwnProperty; // for `window` on <=IE8 + + for (var key in obj) { + if (has.call(obj, key)) { + keys.push(key); + } + } + + return keys; +}; + +/** + * Watch the given `files` for changes + * and invoke `fn(file)` on modification. + * + * @api private + * @param {Array} files + * @param {Function} fn + */ +exports.watch = function(files, fn) { + var options = { interval: 100 }; + files.forEach(function(file) { + debug('file %s', file); + watchFile(file, options, function(curr, prev) { + if (prev.mtime < curr.mtime) { + fn(file); + } + }); + }); +}; + +/** + * Array.isArray (<=IE8) + * + * @api private + * @param {Object} obj + * @return {Boolean} + */ +var isArray = typeof Array.isArray === 'function' ? Array.isArray : function(obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +}; + +exports.isArray = isArray; + +/** + * Buffer.prototype.toJSON polyfill. + * + * @type {Function} + */ +if (typeof Buffer !== 'undefined' && Buffer.prototype) { + Buffer.prototype.toJSON = Buffer.prototype.toJSON || function() { + return Array.prototype.slice.call(this, 0); + }; +} + +/** + * Ignored files. + * + * @api private + * @param {string} path + * @return {boolean} + */ +function ignored(path) { + return !~ignore.indexOf(path); +} + +/** + * Lookup files in the given `dir`. + * + * @api private + * @param {string} dir + * @param {string[]} [ext=['.js']] + * @param {Array} [ret=[]] + * @return {Array} + */ +exports.files = function(dir, ext, ret) { + ret = ret || []; + ext = ext || ['js']; + + var re = new RegExp('\\.(' + ext.join('|') + ')$'); + + readdirSync(dir) + .filter(ignored) + .forEach(function(path) { + path = join(dir, path); + if (statSync(path).isDirectory()) { + exports.files(path, ext, ret); + } else if (path.match(re)) { + ret.push(path); + } + }); + + return ret; +}; + +/** + * Compute a slug from the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.slug = function(str) { + return str + .toLowerCase() + .replace(/ +/g, '-') + .replace(/[^-\w]/g, ''); +}; + +/** + * Strip the function definition from `str`, and re-indent for pre whitespace. + * + * @param {string} str + * @return {string} + */ +exports.clean = function(str) { + str = str + .replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '') + .replace(/^function *\(.*\)\s*\{|\(.*\) *=> *\{?/, '') + .replace(/\s+\}$/, ''); + + var spaces = str.match(/^\n?( *)/)[1].length; + var tabs = str.match(/^\n?(\t*)/)[1].length; + var re = new RegExp('^\n?' + (tabs ? '\t' : ' ') + '{' + (tabs ? tabs : spaces) + '}', 'gm'); + + str = str.replace(re, ''); + + return exports.trim(str); +}; + +/** + * Trim the given `str`. + * + * @api private + * @param {string} str + * @return {string} + */ +exports.trim = function(str) { + return str.replace(/^\s+|\s+$/g, ''); +}; + +/** + * Parse the given `qs`. + * + * @api private + * @param {string} qs + * @return {Object} + */ +exports.parseQuery = function(qs) { + return exports.reduce(qs.replace('?', '').split('&'), function(obj, pair) { + var i = pair.indexOf('='); + var key = pair.slice(0, i); + var val = pair.slice(++i); + + obj[key] = decodeURIComponent(val); + return obj; + }, {}); +}; + +/** + * Highlight the given string of `js`. + * + * @api private + * @param {string} js + * @return {string} + */ +function highlight(js) { + return js + .replace(//g, '>') + .replace(/\/\/(.*)/gm, '//$1') + .replace(/('.*?')/gm, '$1') + .replace(/(\d+\.\d+)/gm, '$1') + .replace(/(\d+)/gm, '$1') + .replace(/\bnew[ \t]+(\w+)/gm, 'new $1') + .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '$1'); +} + +/** + * Highlight the contents of tag `name`. + * + * @api private + * @param {string} name + */ +exports.highlightTags = function(name) { + var code = document.getElementById('mocha').getElementsByTagName(name); + for (var i = 0, len = code.length; i < len; ++i) { + code[i].innerHTML = highlight(code[i].innerHTML); + } +}; + +/** + * If a value could have properties, and has none, this function is called, + * which returns a string representation of the empty value. + * + * Functions w/ no properties return `'[Function]'` + * Arrays w/ length === 0 return `'[]'` + * Objects w/ no properties return `'{}'` + * All else: return result of `value.toString()` + * + * @api private + * @param {*} value The value to inspect. + * @param {string} [type] The type of the value, if known. + * @returns {string} + */ +function emptyRepresentation(value, type) { + type = type || exports.type(value); + + switch (type) { + case 'function': + return '[Function]'; + case 'object': + return '{}'; + case 'array': + return '[]'; + default: + return value.toString(); + } +} + +/** + * Takes some variable and asks `Object.prototype.toString()` what it thinks it + * is. + * + * @api private + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString + * @param {*} value The value to test. + * @returns {string} + * @example + * type({}) // 'object' + * type([]) // 'array' + * type(1) // 'number' + * type(false) // 'boolean' + * type(Infinity) // 'number' + * type(null) // 'null' + * type(new Date()) // 'date' + * type(/foo/) // 'regexp' + * type('type') // 'string' + * type(global) // 'global' + */ +exports.type = function type(value) { + if (value === undefined) { + return 'undefined'; + } else if (value === null) { + return 'null'; + } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { + return 'buffer'; + } + return Object.prototype.toString.call(value) + .replace(/^\[.+\s(.+?)\]$/, '$1') + .toLowerCase(); +}; + +/** + * Stringify `value`. Different behavior depending on type of value: + * + * - If `value` is undefined or null, return `'[undefined]'` or `'[null]'`, respectively. + * - If `value` is not an object, function or array, return result of `value.toString()` wrapped in double-quotes. + * - If `value` is an *empty* object, function, or array, return result of function + * {@link emptyRepresentation}. + * - If `value` has properties, call {@link exports.canonicalize} on it, then return result of + * JSON.stringify(). + * + * @api private + * @see exports.type + * @param {*} value + * @return {string} + */ +exports.stringify = function(value) { + var type = exports.type(value); + + if (!~exports.indexOf(['object', 'array', 'function'], type)) { + if (type !== 'buffer') { + return jsonStringify(value); + } + var json = value.toJSON(); + // Based on the toJSON result + return jsonStringify(json.data && json.type ? json.data : json, 2) + .replace(/,(\n|$)/g, '$1'); + } + + for (var prop in value) { + if (Object.prototype.hasOwnProperty.call(value, prop)) { + return jsonStringify(exports.canonicalize(value), 2).replace(/,(\n|$)/g, '$1'); + } + } + + return emptyRepresentation(value, type); +}; + +/** + * like JSON.stringify but more sense. + * + * @api private + * @param {Object} object + * @param {number=} spaces + * @param {number=} depth + * @returns {*} + */ +function jsonStringify(object, spaces, depth) { + if (typeof spaces === 'undefined') { + // primitive types + return _stringify(object); + } + + depth = depth || 1; + var space = spaces * depth; + var str = isArray(object) ? '[' : '{'; + var end = isArray(object) ? ']' : '}'; + var length = typeof object.length === 'number' ? object.length : exports.keys(object).length; + // `.repeat()` polyfill + function repeat(s, n) { + return new Array(n).join(s); + } + + function _stringify(val) { + switch (exports.type(val)) { + case 'null': + case 'undefined': + val = '[' + val + ']'; + break; + case 'array': + case 'object': + val = jsonStringify(val, spaces, depth + 1); + break; + case 'boolean': + case 'regexp': + case 'symbol': + case 'number': + val = val === 0 && (1 / val) === -Infinity // `-0` + ? '-0' + : val.toString(); + break; + case 'date': + 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': + var json = val.toJSON(); + // Based on the toJSON result + json = json.data && json.type ? json.data : json; + val = '[Buffer: ' + jsonStringify(json, 2, depth + 1) + ']'; + break; + default: + val = (val === '[Function]' || val === '[Circular]') + ? val + : JSON.stringify(val); // string + } + return val; + } + + for (var i in object) { + if (!Object.prototype.hasOwnProperty.call(object, i)) { + continue; // not my business + } + --length; + str += '\n ' + repeat(' ', space) + + (isArray(object) ? '' : '"' + i + '": ') // key + + _stringify(object[i]) // value + + (length ? ',' : ''); // comma + } + + return str + // [], {} + + (str.length !== 1 ? '\n' + repeat(' ', --space) + end : end); +} + +/** + * Test if a value is a buffer. + * + * @api private + * @param {*} value The value to test. + * @return {boolean} True if `value` is a buffer, otherwise false + */ +exports.isBuffer = function(value) { + return typeof Buffer !== 'undefined' && Buffer.isBuffer(value); +}; + +/** + * Return a new Thing that has the keys in sorted order. Recursive. + * + * If the Thing... + * - has already been seen, return string `'[Circular]'` + * - is `undefined`, return string `'[undefined]'` + * - is `null`, return value `null` + * - is some other primitive, return the value + * - is not a primitive or an `Array`, `Object`, or `Function`, return the value of the Thing's `toString()` method + * - is a non-empty `Array`, `Object`, or `Function`, return the result of calling this function again. + * - is an empty `Array`, `Object`, or `Function`, return the result of calling `emptyRepresentation()` + * + * @api private + * @see {@link exports.stringify} + * @param {*} value Thing to inspect. May or may not have properties. + * @param {Array} [stack=[]] Stack of seen values + * @return {(Object|Array|Function|string|undefined)} + */ +exports.canonicalize = function(value, stack) { + var canonicalizedObj; + /* eslint-disable no-unused-vars */ + var prop; + /* eslint-enable no-unused-vars */ + var type = exports.type(value); + function withStack(value, fn) { + stack.push(value); + fn(); + stack.pop(); + } + + stack = stack || []; + + if (exports.indexOf(stack, value) !== -1) { + return '[Circular]'; + } + + switch (type) { + case 'undefined': + case 'buffer': + case 'null': + canonicalizedObj = value; + break; + case 'array': + withStack(value, function() { + canonicalizedObj = exports.map(value, function(item) { + return exports.canonicalize(item, stack); + }); + }); + break; + case 'function': + /* eslint-disable guard-for-in */ + for (prop in value) { + canonicalizedObj = {}; + break; + } + /* eslint-enable guard-for-in */ + if (!canonicalizedObj) { + canonicalizedObj = emptyRepresentation(value, type); + break; + } + /* falls through */ + case 'object': + canonicalizedObj = canonicalizedObj || {}; + withStack(value, function() { + exports.forEach(exports.keys(value).sort(), function(key) { + canonicalizedObj[key] = exports.canonicalize(value[key], stack); + }); + }); + break; + case 'date': + case 'number': + case 'regexp': + case 'boolean': + case 'symbol': + canonicalizedObj = value; + break; + default: + canonicalizedObj = value + ''; + } + + return canonicalizedObj; +}; + +/** + * Lookup file names at the given `path`. + * + * @api public + * @param {string} path Base path to start searching from. + * @param {string[]} extensions File extensions to look for. + * @param {boolean} recursive Whether or not to recurse into subdirectories. + * @return {string[]} An array of paths. + */ +exports.lookupFiles = function lookupFiles(path, extensions, recursive) { + var files = []; + var re = new RegExp('\\.(' + extensions.join('|') + ')$'); + + if (!exists(path)) { + if (exists(path + '.js')) { + path += '.js'; + } else { + files = glob.sync(path); + if (!files.length) { + throw new Error("cannot resolve path (or pattern) '" + path + "'"); + } + return files; + } + } + + try { + var stat = statSync(path); + if (stat.isFile()) { + return path; + } + } catch (err) { + // ignore error + return; + } + + readdirSync(path).forEach(function(file) { + file = join(path, file); + try { + var stat = statSync(file); + if (stat.isDirectory()) { + if (recursive) { + files = files.concat(lookupFiles(file, extensions, recursive)); + } + return; + } + } catch (err) { + // ignore error + return; + } + if (!stat.isFile() || !re.test(file) || basename(file)[0] === '.') { + return; + } + files.push(file); + }); + + return files; +}; + +/** + * Generate an undefined error with a message warning the user. + * + * @return {Error} + */ + +exports.undefinedError = function() { + return new Error('Caught undefined error, did you throw without specifying what?'); +}; + +/** + * Generate an undefined error if `err` is not defined. + * + * @param {Error} err + * @return {Error} + */ + +exports.getError = function(err) { + return err || exports.undefinedError(); +}; + +/** + * @summary + * This Filter based on `mocha-clean` module.(see: `github.com/rstacruz/mocha-clean`) + * @description + * When invoking this function you get a filter function that get the Error.stack as an input, + * and return a prettify output. + * (i.e: strip Mocha and internal node functions from stack trace). + * @returns {Function} + */ +exports.stackTraceFilter = function() { + // TODO: Replace with `process.browser` + var slash = '/'; + var is = typeof document === 'undefined' ? { node: true } : { browser: true }; + var cwd = is.node + ? process.cwd() + slash + : (typeof location === 'undefined' ? window.location : location).href.replace(/\/[^\/]*$/, '/'); + + function isMochaInternal(line) { + return (~line.indexOf('node_modules' + slash + 'mocha' + slash)) + || (~line.indexOf('components' + slash + 'mochajs' + slash)) + || (~line.indexOf('components' + slash + 'mocha' + slash)) + || (~line.indexOf(slash + 'mocha.js')); + } + + function isNodeInternal(line) { + return (~line.indexOf('(timers.js:')) + || (~line.indexOf('(events.js:')) + || (~line.indexOf('(node.js:')) + || (~line.indexOf('(module.js:')) + || (~line.indexOf('GeneratorFunctionPrototype.next (native)')) + || false; + } + + return function(stack) { + stack = stack.split('\n'); + + stack = exports.reduce(stack, function(list, line) { + if (isMochaInternal(line)) { + return list; + } + + if (is.node && isNodeInternal(line)) { + return list; + } + + // Clean up cwd(absolute) + if (/\(?.+:\d+:\d+\)?$/.test(line)) { + line = line.replace(cwd, ''); + } + + list.push(line); + return list; + }, []); + + return stack.join('\n'); + }; +}; + +}).call(this,require('_process'),require("buffer").Buffer) +},{"_process":58,"buffer":45,"debug":2,"fs":43,"glob":43,"path":43,"to-iso-string":72,"util":75}],40:[function(require,module,exports){ +'use strict' + +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +function init () { + var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' + for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i + } + + revLookup['-'.charCodeAt(0)] = 62 + revLookup['_'.charCodeAt(0)] = 63 +} + +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') + } + + // 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 + + // 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":58,"stream":59,"util":75}],43:[function(require,module,exports){ +arguments[4][41][0].apply(exports,arguments) +},{"dup":41}],44:[function(require,module,exports){ +(function (global){ +'use strict'; + +var buffer = require('buffer'); +var Buffer = buffer.Buffer; +var SlowBuffer = buffer.SlowBuffer; +var MAX_LEN = buffer.kMaxLength || 2147483647; +exports.alloc = function alloc(size, fill, encoding) { + if (typeof Buffer.alloc === 'function') { + return Buffer.alloc(size, fill, encoding); + } + if (typeof encoding === 'number') { + throw new TypeError('encoding must not be number'); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + var enc = encoding; + var _fill = fill; + if (_fill === undefined) { + enc = undefined; + _fill = 0; + } + var buf = new Buffer(size); + if (typeof _fill === 'string') { + var fillBuf = new Buffer(_fill, enc); + var flen = fillBuf.length; + var i = -1; + while (++i < size) { + buf[i] = fillBuf[i % flen]; + } + } else { + buf.fill(_fill); + } + return buf; +} +exports.allocUnsafe = function allocUnsafe(size) { + if (typeof Buffer.allocUnsafe === 'function') { + return Buffer.allocUnsafe(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size > MAX_LEN) { + throw new RangeError('size is too large'); + } + return new Buffer(size); +} +exports.from = function from(value, encodingOrOffset, length) { + if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { + return Buffer.from(value, encodingOrOffset, length); + } + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number'); + } + if (typeof value === 'string') { + return new Buffer(value, encodingOrOffset); + } + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + var offset = encodingOrOffset; + if (arguments.length === 1) { + return new Buffer(value); + } + if (typeof offset === 'undefined') { + offset = 0; + } + var len = length; + if (typeof len === 'undefined') { + len = value.byteLength - offset; + } + if (offset >= value.byteLength) { + throw new RangeError('\'offset\' is out of bounds'); + } + if (len > value.byteLength - offset) { + throw new RangeError('\'length\' is out of bounds'); + } + return new Buffer(value.slice(offset, offset + len)); + } + if (Buffer.isBuffer(value)) { + var out = new Buffer(value.length); + value.copy(out, 0, 0, value.length); + return out; + } + if (value) { + if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { + return new Buffer(value); + } + if (value.type === 'Buffer' && Array.isArray(value.data)) { + return new Buffer(value.data); + } + } + + throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); +} +exports.allocUnsafeSlow = function allocUnsafeSlow(size) { + if (typeof Buffer.allocUnsafeSlow === 'function') { + return Buffer.allocUnsafeSlow(size); + } + if (typeof size !== 'number') { + throw new TypeError('size must be a number'); + } + if (size >= MAX_LEN) { + throw new RangeError('size is too large'); + } + return new SlowBuffer(size); +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"buffer":45}],45:[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('isarray') + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Due to various browser bugs, sometimes the Object implementation will be used even + * when the browser supports typed arrays. + * + * Note: + * + * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + + * 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 = 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 } + return arr.foo() === 42 && // typed array instances can be augmented + 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 + ? 0x7fffffff + : 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 +} + +/** + * 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. + * + * The `Uint8Array` prototype remains unmodified. + */ + +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') { + 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) +} + +Buffer.poolSize = 8192 // not used by this implementation + +// TODO: Legacy, not needed anymore. Remove in next major version. +Buffer._augment = function (arr) { + arr.__proto__ = Buffer.prototype + return arr +} + +function from (that, value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('"value" argument must not be a number') + } + + if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { + return fromArrayBuffer(that, value, encodingOrOffset, length) + } + + if (typeof value === 'string') { + return fromString(that, value, encodingOrOffset) + } + + return fromObject(that, value) +} + +/** + * 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 (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 + }) + } +} + +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be a number') + } +} + +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) +} + +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(null, size, fill, encoding) +} + +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 +} + +/** + * 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 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 = createBuffer(that, length) + for (var i = 0; i < length; i += 1) { + that[i] = array[i] & 255 + } + return that +} + +function fromArrayBuffer (that, array, byteOffset, length) { + array.byteLength // this throws if `array` is not a valid ArrayBuffer + + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('\'offset\' is out of bounds') + } + + 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) + } + + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Return an augmented `Uint8Array` instance, for best performance + that = array + that.__proto__ = Buffer.prototype + } else { + // Fallback: Return an object instance of the Buffer class + 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 + } + + 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) + } + + 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) { + // Note: cannot use `length < kMaxLength` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= kMaxLength()) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength().toString(16) + ' bytes') + } + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 + } + return Buffer.alloc(+length) +} + +Buffer.isBuffer = function isBuffer (b) { + return !!(b != null && b._isBuffer) +} + +Buffer.compare = function compare (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError('Arguments must be Buffers') + } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + 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 + if (y < x) return 1 + return 0 +} + +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.concat = function concat (list, length) { + if (!isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + + if (list.length === 0) { + return Buffer.alloc(0) + } + + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; i++) { + length += list[i].length + } + } + + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; i++) { + 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 buffer +} + +function byteLength (string, encoding) { + 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 + + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'binary': + // Deprecated + case 'raw': + case 'raws': + return len + case 'utf8': + case 'utf-8': + case undefined: + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) return utf8ToBytes(string).length // assume utf8 + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} +Buffer.byteLength = byteLength + +function slowToString (encoding, start, end) { + var loweredCase = false + + // 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' + + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) + + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) + + case 'ascii': + return asciiSlice(this, start, end) + + case 'binary': + return binarySlice(this, start, end) + + case 'base64': + return base64Slice(this, start, end) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } + } +} + +// 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 '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) str += ' ... ' + } + return '' +} + +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, 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 + if (byteOffset >= this.length) return -1 + + // Negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + + if (typeof val === 'string') { + val = Buffer.from(val, encoding) + } + + if (Buffer.isBuffer(val)) { + // 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, encoding) + } + + throw new TypeError('val must be string, number or Buffer') +} + +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +} + +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(parsed)) return i + buf[offset + i] = parsed + } + return i +} + +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} + +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} + +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} + +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} + +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} + +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset | 0 + if (isFinite(length)) { + length = length | 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined + } + // legacy write(string, encoding, offset, length) - remove in v0.13 + } else { + 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') + } + + if (!encoding) encoding = 'utf8' + + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) + + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) + + case 'ascii': + return asciiWrite(this, string, offset, length) + + case 'binary': + return binaryWrite(this, string, offset, length) + + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) + + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) + + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} + +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] + + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 + + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint + + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } + + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } + + res.push(codePoint) + i += bytesPerSequence + } + + return decodeCodePointsArray(res) +} + +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 + +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } + + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} + +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i] & 0x7F) + } + return ret +} + +function binarySlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} + +function hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} + +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end + + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len + } + + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } + + if (end < start) end = start + + var newBuf + if (Buffer.TYPED_ARRAY_SUPPORT) { + newBuf = this.subarray(start, end) + newBuf.__proto__ = Buffer.prototype + } else { + var sliceLen = end - start + newBuf = new Buffer(sliceLen, undefined) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + } + + return newBuf +} + +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +} + +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + + return val +} + +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) + } + + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul + } + + return val +} + +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} + +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} + +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} + +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} + +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset | 0 + byteLength = byteLength | 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) + + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul + } + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val +} + +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} + +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} + +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} + +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} + +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} + +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} + +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} + +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} + +function checkInt (buf, value, offset, ext, max, min) { + 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) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } + + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + byteLength = 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 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } + + return offset + byteLength +} + +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = (value & 0xff) + return offset + 1 +} + +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = 0 + var mul = 1 + 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 + } + + return offset + byteLength +} + +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) { + var limit = Math.pow(2, 8 * byteLength - 1) + + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } + + var i = byteLength - 1 + var mul = 1 + 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 + } + + return offset + byteLength +} + +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset | 0 + 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 & 0xff) + return offset + 1 +} + +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + } else { + objectWriteUInt16(this, value, offset, true) + } + return offset + 2 +} + +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + } else { + objectWriteUInt16(this, value, offset, false) + } + return offset + 2 +} + +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else { + objectWriteUInt32(this, value, offset, true) + } + return offset + 4 +} + +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset | 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + } else { + objectWriteUInt32(this, value, offset, false) + } + return offset + 4 +} + +function checkIEEE754 (buf, value, offset, ext, max, min) { + 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) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} + +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} + +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} + +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start + + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 + + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') + } + if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start + } + + var len = end - start + var i + + if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (i = len - 1; i >= 0; i--) { + target[i + targetStart] = this[i + start] + } + } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + // ascending copy from start + for (i = 0; i < len; i++) { + target[i + targetStart] = this[i + start] + } + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, start + len), + targetStart + ) + } + + return len +} + +// 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) { + return this + } + + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 + + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; i++) { + this[i] = val + } + } else { + var bytes = Buffer.isBuffer(val) + ? val + : utf8ToBytes(new Buffer(val, encoding).toString()) + var len = bytes.length + for (i = 0; i < end - start; i++) { + this[i + start] = bytes[i % len] + } + } + + return this +} + +// HELPER FUNCTIONS +// ================ + +var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g + +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] + + for (var i = 0; i < length; i++) { + codePoint = string.charCodeAt(i) + + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } + + // valid lead + leadSurrogate = codePoint + + continue + } + + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } + + // valid surrogate pair + 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) + } + + leadSurrogate = null + + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') + } + } + + return bytes +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + if ((units -= 2) < 0) break + + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} + +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] + } + return i +} + +function isnan (val) { + return val !== val // eslint-disable-line no-self-compare +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"base64-js":40,"ieee754":52,"isarray":46}],46:[function(require,module,exports){ +var toString = {}.toString; + +module.exports = Array.isArray || function (arr) { + return toString.call(arr) == '[object Array]'; +}; + +},{}],47:[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(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +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; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +}).call(this,{"isBuffer":require("../../is-buffer/index.js")}) +},{"../../is-buffer/index.js":54}],48:[function(require,module,exports){ +/* See LICENSE file for terms of use */ + +/* + * 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); + } + + 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 n; + } + + // 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 || []; + + var i; + + for (i = 0; i < stack.length; i += 1) { + if (stack[i] === obj) { + return replacementStack[i]; + } + } + + 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(); + } else { + canonicalizedObj = obj; + } + return canonicalizedObj; + } + + function buildValues(components, newString, oldString, useLongestToken) { + var componentPos = 0, + componentLen = components.length, + newPos = 0, + oldPos = 0; + + 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; + }); + + component.value = value.join(''); + } else { + component.value = newString.slice(newPos, newPos + component.count).join(''); + } + newPos += component.count; + + // Common case + if (!component.added) { + oldPos += component.count; + } + } else { + component.value = oldString.slice(oldPos, oldPos + component.count).join(''); + oldPos += component.count; + + // 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; + } + } + } + + return components; + } + + function Diff(ignoreWhitespace) { + this.ignoreWhitespace = ignoreWhitespace; + } + Diff.prototype = { + diff: function(oldString, newString, callback) { + var self = this; + + function done(value) { + if (callback) { + setTimeout(function() { callback(undefined, value); }, 0); + return true; + } else { + return value; + } + } + + // 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 }]); + } + + 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('')}]); + } + + // 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; + } + + 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; + } + + // 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); + } + + oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath); + + // 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; + } + } + + editLength++; + } + + // 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 (!execEditLength()) { + exec(); + } + }, 0); + }()); + } else { + while (editLength <= maxEditLength) { + var ret = execEditLength(); + if (ret) { + return ret; + } + } + } + }, + + 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, + + 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}); + } + + basePath.newPos = newPos; + return oldPos; + }, + + equals: function(left, right) { + var reWhitespace = /\S/; + return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)); + }, + tokenize: function(value) { + return value.split(''); + } + }; + + var CharDiff = new Diff(); + + var WordDiff = new Diff(true); + var WordWithSpaceDiff = new Diff(); + WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\s+|\b)/)); + }; + + var CssDiff = new Diff(true); + CssDiff.tokenize = function(value) { + return removeEmpty(value.split(/([{}:;,]|\s+)/)); + }; + + var LineDiff = new Diff(); + + var TrimmedLineDiff = new Diff(); + TrimmedLineDiff.ignoreTrim = true; + + 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]; + + // 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 retLines; + }; + + var PatchDiff = new Diff(); + PatchDiff.tokenize = function(value) { + var ret = [], + linesAndNewlines = value.split(/(\n|\r\n)/); + + // Ignore the final empty token that occurs if the string ends with a new line + if (!linesAndNewlines[linesAndNewlines.length - 1]) { + linesAndNewlines.pop(); + } + + // Merge the content and line separators into single tokens + for (var i = 0; i < linesAndNewlines.length; i++) { + var line = linesAndNewlines[i]; + + if (i % 2) { + ret[ret.length - 1] += line; + } else { + ret.push(line); + } + } + return ret; + }; + + var SentenceDiff = new Diff(); + SentenceDiff.tokenize = function(value) { + return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/)); + }; + + 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, + + 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); }, + + diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); }, + + 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 = []; + + 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)); + + var diff = PatchDiff.diff(oldStr, newStr); + diff.push({value: '', lines: []}); // Append an empty value to make cleanup easier + + // 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; + + // 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 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 (current.added || current.removed) { + // If we have previous context, start with that + if (!oldRangeStart) { + var prev = diff[i - 1]; + oldRangeStart = oldLine; + newRangeStart = newLine; + + if (prev) { + curRange = contextLines(prev.lines.slice(-4)); + oldRangeStart -= curRange.length; + newRangeStart -= curRange.length; + } + } + + // Output our changes + curRange.push.apply(curRange, map(lines, function(entry) { + return (current.added ? '+' : '-') + entry; + })); + eofNL(curRange, i, current); + + // 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); + } + + oldRangeStart = 0; + newRangeStart = 0; + curRange = []; + } + } + oldLine += lines.length; + newLine += lines.length; + } + } + + return ret.join('\n') + '\n'; + }, + + createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) { + return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader); + }, + + applyPatch: function(oldStr, uniDiff) { + var diffstr = uniDiff.split('\n'), + hunks = [], + i = 0, + remEOFNL = false, + addEOFNL = false; + + // Skip to the first change hunk + while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) { + i++; + } + + // 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; + } + } + } + + // 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)); + } + + // Handle EOFNL insertion/removal + if (remEOFNL) { + while (!lines[lines.length - 1]) { + lines.pop(); + } + } else if (addEOFNL) { + lines.push(''); + } + return lines.join('\n'); + }, + + 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(''); + } + + ret.push(escapeHTML(change.value)); + + if (change.added) { + ret.push(''); + } else if (change.removed) { + ret.push(''); + } + } + return ret.join(''); + }, + + // 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; + } + + ret.push([operation, change.value]); + } + return ret; + }, + + canonicalize: canonicalize + }; + + /*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)); + +},{}],49:[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, '\\$&'); +}; + +},{}],50:[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. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// 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; + +// 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; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // 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]; + + 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); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // 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); + + 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]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + 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; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + 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'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // 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; + } + + // 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; + } + + listeners = this._events[type]; + + 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]; + + return this; +}; + +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; +}; + +EventEmitter.prototype.listenerCount = function(type) { + if (this._events) { + var evlistener = this._events[type]; + + if (isFunction(evlistener)) + return 1; + else if (evlistener) + return evlistener.length; + } + return 0; +}; + +EventEmitter.listenerCount = function(emitter, type) { + return emitter.listenerCount(type); +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +},{}],51:[function(require,module,exports){ +(function (process){ +// Growl - Copyright TJ Holowaychuk (MIT Licensed) + +/** + * Module dependencies. + */ + +var exec = require('child_process').exec + , fs = require('fs') + , path = require('path') + , exists = fs.existsSync || path.existsSync + , os = require('os') + , quote = JSON.stringify + , cmd; + +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; + } +} + +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; +} + +/** + * Expose `growl`. + */ + +exports = module.exports = growl; + +/** + * Node-growl version. + */ + +exports.version = '1.4.1' + +/** + * 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 + */ + +function growl(msg, options, fn) { + var image + , args + , options = options || {} + , fn = fn || function(){}; + + if (options.exec) { + cmd = { + type: "Custom" + , pkg: options.exec + , range: [] + }; + } + + // noop + if (!cmd) return fn(new Error('growl not supported on this platform')); + args = [cmd.pkg]; + + // 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; + } + } + + // sticky + if (options.sticky) args.push(cmd.sticky); + + // 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); + } + } + + //sound + if(options.sound && cmd.type === 'Darwin-NotificationCenter'){ + args.push(cmd.sound, options.sound) + } + + // name + if (options.name && cmd.type === "Darwin-Growl") { + args.push('--name', options.name); + } + + 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 '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; + 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; + } + + // execute + exec(args.join(' '), fn); +}; + +}).call(this,require('_process')) +},{"_process":58,"child_process":43,"fs":43,"os":56,"path":43}],52:[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 +} + +},{}],53:[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 + } +} + +},{}],54:[function(require,module,exports){ +/** + * Determine if an object is Buffer + * + * Author: Feross Aboukhadijeh + * License: MIT + * + * `npm install is-buffer` + */ + +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)) + )) +} + +},{}],55:[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; + + p = path.resolve(p); + + 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; + + // 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; + } + } + + return made; +}; + +}).call(this,require('_process')) +},{"_process":58,"fs":43,"path":43}],56:[function(require,module,exports){ +exports.endianness = function () { return 'LE' }; + +exports.hostname = function () { + if (typeof location !== 'undefined') { + return location.hostname + } + else return ''; +}; + +exports.loadavg = function () { return [] }; + +exports.uptime = function () { return 0 }; + +exports.freemem = function () { + return Number.MAX_VALUE; +}; + +exports.totalmem = function () { + return Number.MAX_VALUE; +}; + +exports.cpus = function () { return [] }; + +exports.type = function () { return 'Browser' }; + +exports.release = function () { + if (typeof navigator !== 'undefined') { + return navigator.appVersion; + } + return ''; +}; + +exports.networkInterfaces += exports.getNetworkInterfaces += function () { return {} }; + +exports.arch = function () { return 'javascript' }; + +exports.platform = function () { return 'browser' }; + +exports.tmpdir = exports.tmpDir = function () { + return '/tmp'; +}; + +exports.EOL = '\n'; + +},{}],57:[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); + }); + } +} + +}).call(this,require('_process')) +},{"_process":58}],58:[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() { + if (!draining || !currentQueue) { + return; + } + draining = false; + if (currentQueue.length) { + queue = currentQueue.concat(queue); + } else { + queueIndex = -1; + } + if (queue.length) { + drainQueue(); + } +} + +function drainQueue() { + if (draining) { + return; + } + 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); +} + +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); + } +}; + +// 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 = {}; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +}; + +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; +process.umask = function() { return 0; }; + +},{}],59:[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 = Stream; + +var EE = require('events').EventEmitter; +var inherits = require('inherits'); + +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'); + +// Backwards-compat with node 0.4.x +Stream.Stream = Stream; + + + +// old-style streams. Note that the pipe method (the only relevant +// part of this class) is overridden in the Readable class. + +function Stream() { + EE.call(this); +} + +Stream.prototype.pipe = function(dest, options) { + var source = this; + + function ondata(chunk) { + if (dest.writable) { + if (false === dest.write(chunk) && source.pause) { + source.pause(); + } + } + } + + source.on('data', ondata); + + function ondrain() { + if (source.readable && source.resume) { + source.resume(); + } + } + + dest.on('drain', ondrain); + + // 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); + } + + var didOnEnd = false; + function onend() { + if (didOnEnd) return; + didOnEnd = true; + + dest.end(); + } + + + function onclose() { + if (didOnEnd) return; + didOnEnd = true; + + if (typeof dest.destroy === 'function') dest.destroy(); + } + + // 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. + } + } + + 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); + + source.removeListener('end', onend); + source.removeListener('close', onclose); + + source.removeListener('error', onerror); + dest.removeListener('error', onerror); + + source.removeListener('end', cleanup); + source.removeListener('close', cleanup); + + dest.removeListener('close', cleanup); + } + + source.on('end', cleanup); + source.on('close', cleanup); + + dest.on('close', cleanup); + + dest.emit('pipe', source); + + // Allow for unix-like usage: A.pipe(B).pipe(C) + return dest; +}; + +},{"events":50,"inherits":53,"readable-stream/duplex.js":61,"readable-stream/passthrough.js":67,"readable-stream/readable.js":68,"readable-stream/transform.js":69,"readable-stream/writable.js":70}],60:[function(require,module,exports){ +arguments[4][46][0].apply(exports,arguments) +},{"dup":46}],61:[function(require,module,exports){ +module.exports = require("./lib/_stream_duplex.js") + +},{"./lib/_stream_duplex.js":62}],62:[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'); +/**/ + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Readable = require('./_stream_readable'); +var Writable = require('./_stream_writable'); + +util.inherits(Duplex, Readable); + +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]; +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + + Readable.call(this, options); + Writable.call(this, options); + + if (options && options.readable === false) this.readable = false; + + if (options && options.writable === false) this.writable = false; + + this.allowHalfOpen = true; + if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; + + this.once('end', onend); +} + +// 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; + + // no more data can be written. + // But allow more writes to happen in this tick. + processNextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} +},{"./_stream_readable":64,"./_stream_writable":66,"core-util-is":47,"inherits":53,"process-nextick-args":57}],63:[function(require,module,exports){ +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + +'use strict'; + +module.exports = PassThrough; + +var Transform = require('./_stream_transform'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + + Transform.call(this, options); +} + +PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); +}; +},{"./_stream_transform":65,"core-util-is":47,"inherits":53}],64:[function(require,module,exports){ +(function (process){ +'use strict'; + +module.exports = Readable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var isArray = require('isarray'); +/**/ + +Readable.ReadableState = ReadableState; + +/**/ +var EE = require('events').EventEmitter; + +var EElistenerCount = function (emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; +/**/ +var bufferShim = require('buffer-shims'); +/**/ + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var debugUtil = require('util'); +var debug = void 0; +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + +var StringDecoder; + +util.inherits(Readable, Stream); + +var hasPrependListener = typeof EE.prototype.prependListener === 'function'; + +function prependListener(emitter, event, fn) { + if (hasPrependListener) return emitter.prependListener(event, fn); + + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. This is here + // only because this code needs to continue to work with older versions + // of Node.js that do not include the prependListener() method. The goal + // is to eventually remove this hack. + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; +} + +var Duplex; +function ReadableState(options, stream) { + Duplex = Duplex || require('./_stream_duplex'); + + options = options || {}; + + // 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.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.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // 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'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = 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; + } +} + +var Duplex; +function Readable(options) { + Duplex = Duplex || require('./_stream_duplex'); + + if (!(this instanceof Readable)) return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + if (options && typeof options.read === 'function') this._read = options.read; + + Stream.call(this); +} + +// 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.objectMode && typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = bufferShim.from(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function (chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; + +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 (!addToFront) state.reading = false; + + // 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); + + if (state.needReadable) emitReadable(stream); + } + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + +// 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); +} + +// 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 > 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 howMuchToRead(n, state) { + if (state.length === 0 && state.ended) return 0; + + if (state.objectMode) return n === 0 ? 0 : 1; + + 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 (n <= 0) return 0; + + // 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); + + // 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; +} + +// 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 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; + } + + n = howMuchToRead(n, state); + + // 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; + } + + // 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 need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // 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); + } + + // 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; + } + + // 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; + + if (ret === null) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // 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); + + if (ret !== null) this.emit('data', ret); + + return ret; +}; + +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 er; +} + +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; + + // 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) processNextTick(emitReadable_, stream);else emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + +// 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); + } +} + +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; +} + +// 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; + + 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); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // 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); + + 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); + + cleanedUp = true; + + // 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(); + } + + 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. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', src._readableState.awaitDrain); + src._readableState.awaitDrain++; + } + src.pause(); + } + } + + // 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); + } + + // Make sure our error handler is attached before userland ones. + prependListener(dest, 'error', onerror); + + // 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); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + 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; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) return 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; + + if (!dest) dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var _i = 0; _i < len; _i++) { + dests[_i].emit('unpipe', this); + }return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// 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(); + } + + 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); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} + +// 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; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + processNextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + if (!state.reading) { + debug('resume read 0'); + stream.read(0); + } + + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +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; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} + +// 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; + + 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); + } + + self.push(null); + }); + + 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; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // 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); + } + } + + // 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; + +// 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; + + // nothing in the list, definitely empty. + if (list.length === 0) return null; + + 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 = bufferShim.allocUnsafe(n); + + 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); + + if (stringMode) ret += _buf.slice(0, cpy);else _buf.copy(ret, c, 0, cpy); + + if (cpy < _buf.length) list[0] = _buf.slice(cpy);else list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // 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'); + + if (!state.endEmitted) { + state.ended = true; + processNextTick(endReadableNT, state, stream); + } +} + +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'); + } +} + +function forEach(xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +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":62,"_process":58,"buffer":45,"buffer-shims":44,"core-util-is":47,"events":50,"inherits":53,"isarray":60,"process-nextick-args":57,"string_decoder/":71,"util":41}],65:[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. + +'use strict'; + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + +function TransformState(stream) { + this.afterTransform = function (er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; + this.writeencoding = 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 (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); + } +} + +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; + } + + this.once('prefinish', function () { + if (typeof this._flush === 'function') this._flush(function (er) { + done(stream, er); + });else done(stream); + }); +} + +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 (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; + } +}; + +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'); + + return stream.push(null); +} +},{"./_stream_duplex":62,"core-util-is":47,"inherits":53}],66:[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'; + +module.exports = Writable; + +/**/ +var processNextTick = require('process-nextick-args'); +/**/ + +/**/ +var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; +/**/ + +Writable.WritableState = WritableState; + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +/**/ +var internalUtil = { + deprecate: require('util-deprecate') +}; +/**/ + +/**/ +var Stream; +(function () { + try { + Stream = require('st' + 'ream'); + } catch (_) {} finally { + if (!Stream) Stream = require('events').EventEmitter; + } +})(); +/**/ + +var Buffer = require('buffer').Buffer; +/**/ +var bufferShim = require('buffer-shims'); +/**/ + +util.inherits(Writable, Stream); + +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'); + + options = options || {}; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) this.objectMode = this.objectMode || !!options.writableObjectMode; + + // 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; + + // cast to ints. + this.highWaterMark = ~ ~this.highWaterMark; + + 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; + + // 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; + + // 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; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // 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.bufferedRequest = null; + this.lastBufferedRequest = null; + + // 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; + + // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + this.corkedRequestsFree = 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 (_) {} +})(); + +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; + } + + 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 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; + var er = false; + // Always throw error if a null is written + // if we are not in object mode then throw + // if it is not a buffer, string, or undefined. + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { + stream.emit('error', er); + processNextTick(cb, er); + valid = false; + } + return valid; +} + +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + 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 ret; +}; + +Writable.prototype.cork = function () { + var state = this._writableState; + + state.corked++; +}; + +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); + } +}; + +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; + return this; +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = bufferShim.from(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); + + if (Buffer.isBuffer(chunk)) encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + 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.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); + } + + return ret; +} + +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; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + if (sync) processNextTick(cb, er);else cb(er); + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + 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); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// 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'); + } +} + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + 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; + } + + doWrite(stream, state, true, state.length, buffer, '', holder.finish); + + // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + state.pendingcb++; + state.lastBufferedRequest = null; + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + } 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; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequestCount = 0; + state.bufferedRequest = entry; + state.bufferProcessing = false; +} + +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new Error('not implemented')); +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) endWritable(this, state, cb); +}; + +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +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 need; +} + +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; +} + +// 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; + + this.next = null; + this.entry = null; + + this.finish = function (err) { + var entry = _this.entry; + _this.entry = null; + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } + if (state.corkedRequestsFree) { + state.corkedRequestsFree.next = _this; + } else { + state.corkedRequestsFree = _this; + } + }; +} +}).call(this,require('_process')) +},{"./_stream_duplex":62,"_process":58,"buffer":45,"buffer-shims":44,"core-util-is":47,"events":50,"inherits":53,"process-nextick-args":57,"util-deprecate":73}],67:[function(require,module,exports){ +module.exports = require("./lib/_stream_passthrough.js") + +},{"./lib/_stream_passthrough.js":63}],68:[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'); + +if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { + module.exports = Stream; +} + +}).call(this,require('_process')) +},{"./lib/_stream_duplex.js":62,"./lib/_stream_passthrough.js":63,"./lib/_stream_readable.js":64,"./lib/_stream_transform.js":65,"./lib/_stream_writable.js":66,"_process":58}],69:[function(require,module,exports){ +module.exports = require("./lib/_stream_transform.js") + +},{"./lib/_stream_transform.js":65}],70:[function(require,module,exports){ +module.exports = require("./lib/_stream_writable.js") + +},{"./lib/_stream_writable.js":66}],71:[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 Buffer = require('buffer').Buffer; + +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; + } + } + + +function assertEncoding(encoding) { + if (encoding && !isBufferEncoding(encoding)) { + throw new Error('Unknown encoding: ' + encoding); + } +} + +// 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; + } + + // 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; +}; + + +// 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; + + // add the new bytes to the char buffer + buffer.copy(this.charBuffer, this.charReceived, 0, available); + this.charReceived += available; + + if (this.charReceived < this.charLength) { + // still not enough chars in this buffer? wait for more ... + return ''; + } + + // remove bytes belonging to the current character from the buffer + buffer = buffer.slice(available, buffer.length); + + // get the character that was split + charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); + + // 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 there are no more bytes in this buffer, just emit our char + if (buffer.length === 0) { + return charStr; + } + break; + } + + // determine and set charLength / charReceived + this.detectIncompleteChar(buffer); + + 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; + } + + charStr += buffer.toString(this.encoding, 0, end); + + 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); + } + + // 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]; + + // See http://en.wikipedia.org/wiki/UTF-8#Description + + // 110XXXXX + if (i == 1 && c >> 5 == 0x06) { + this.charLength = 2; + break; + } + + // 1110XXXX + if (i <= 2 && c >> 4 == 0x0E) { + this.charLength = 3; + break; + } + + // 11110XXX + if (i <= 3 && c >> 3 == 0x1E) { + this.charLength = 4; + break; + } + } + this.charReceived = i; +}; + +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":45}],72:[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; +} +},{}],73:[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); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +} + +/** + * Checks `localStorage` for boolean values for the given `name`. + * + * @param {String} name + * @returns {Boolean} + * @api private + */ + +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 : {}) +},{}],74:[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'; +} +},{}],75:[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); + } + warned = true; + } + return fn.apply(this, arguments); + } + + 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' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +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; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // 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); + } + + // 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); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + 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); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +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(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +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 (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; +} + + +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); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// 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; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +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; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 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(' '); +} + + +// 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)); +}; + + +/** + * 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; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + 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":74,"_process":58,"inherits":53}]},{},[1]); diff --git a/node_modules/mocha/node_modules/.bin/jade b/node_modules/mocha/node_modules/.bin/jade new file mode 120000 index 0000000..571fae7 --- /dev/null +++ b/node_modules/mocha/node_modules/.bin/jade @@ -0,0 +1 @@ +../jade/bin/jade \ No newline at end of file diff --git a/node_modules/mocha/node_modules/.bin/mkdirp b/node_modules/mocha/node_modules/.bin/mkdirp new file mode 120000 index 0000000..017896c --- /dev/null +++ b/node_modules/mocha/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/bin/cmd.js \ No newline at end of file diff --git a/node_modules/mocha/node_modules/.bin/supports-color b/node_modules/mocha/node_modules/.bin/supports-color new file mode 120000 index 0000000..af0f05e --- /dev/null +++ b/node_modules/mocha/node_modules/.bin/supports-color @@ -0,0 +1 @@ +../supports-color/cli.js \ No newline at end of file diff --git a/node_modules/mocha/node_modules/commander/Readme.md b/node_modules/mocha/node_modules/commander/Readme.md new file mode 100644 index 0000000..7bb60b2 --- /dev/null +++ b/node_modules/mocha/node_modules/commander/Readme.md @@ -0,0 +1,208 @@ +# Commander.js + + The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander). + + [![Build Status](https://api.travis-ci.org/visionmedia/commander.js.svg)](http://travis-ci.org/visionmedia/commander.js) + +## Installation + + $ npm install commander + +## Option parsing + + Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.0.1') + .option('-p, --peppers', 'Add peppers') + .option('-P, --pineapple', 'Add pineapple') + .option('-b, --bbq', 'Add bbq sauce') + .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') + .parse(process.argv); + +console.log('you ordered a pizza with:'); +if (program.peppers) console.log(' - peppers'); +if (program.pineapple) console.log(' - pineapple'); +if (program.bbq) console.log(' - bbq'); +console.log(' - %s cheese', program.cheese); +``` + + Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. + +## Automated --help + + The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: + +``` + $ ./examples/pizza --help + + Usage: pizza [options] + + Options: + + -V, --version output the version number + -p, --peppers Add peppers + -P, --pineapple Add pineapple + -b, --bbq Add bbq sauce + -c, --cheese Add the specified type of cheese [marble] + -h, --help output usage information + +``` + +## Coercion + +```js +function range(val) { + return val.split('..').map(Number); +} + +function list(val) { + return val.split(','); +} + +function collect(val, memo) { + memo.push(val); + return memo; +} + +function increaseVerbosity(v, total) { + return total + 1; +} + +program + .version('0.0.1') + .usage('[options] ') + .option('-i, --integer ', 'An integer argument', parseInt) + .option('-f, --float ', 'A float argument', parseFloat) + .option('-r, --range ..', 'A range', range) + .option('-l, --list ', 'A list', list) + .option('-o, --optional [value]', 'An optional value') + .option('-c, --collect [value]', 'A repeatable value', collect, []) + .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0) + .parse(process.argv); + +console.log(' int: %j', program.integer); +console.log(' float: %j', program.float); +console.log(' optional: %j', program.optional); +program.range = program.range || []; +console.log(' range: %j..%j', program.range[0], program.range[1]); +console.log(' list: %j', program.list); +console.log(' collect: %j', program.collect); +console.log(' verbosity: %j', program.verbose); +console.log(' args: %j', program.args); +``` + +## Custom help + + You can display arbitrary `-h, --help` information + by listening for "--help". Commander will automatically + exit once you are done so that the remainder of your program + does not execute causing undesired behaviours, for example + in the following executable "stuff" will not output when + `--help` is used. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('../'); + +function list(val) { + return val.split(',').map(Number); +} + +program + .version('0.0.1') + .option('-f, --foo', 'enable some foo') + .option('-b, --bar', 'enable some bar') + .option('-B, --baz', 'enable some baz'); + +// must be before .parse() since +// node's emit() is immediate + +program.on('--help', function(){ + console.log(' Examples:'); + console.log(''); + console.log(' $ custom-help --help'); + console.log(' $ custom-help -h'); + console.log(''); +}); + +program.parse(process.argv); + +console.log('stuff'); +``` + +yielding the following help output: + +``` + +Usage: custom-help [options] + +Options: + + -h, --help output usage information + -V, --version output the version number + -f, --foo enable some foo + -b, --bar enable some bar + -B, --baz enable some baz + +Examples: + + $ custom-help --help + $ custom-help -h + +``` + +## .outputHelp() + + Output help information without exiting. + +## .help() + + Output help information and exit immediately. + +## Links + + - [API documentation](http://visionmedia.github.com/commander.js/) + - [ascii tables](https://github.com/LearnBoost/cli-table) + - [progress bars](https://github.com/visionmedia/node-progress) + - [more progress bars](https://github.com/substack/node-multimeter) + - [examples](https://github.com/visionmedia/commander.js/tree/master/examples) + +## License + +(The MIT License) + +Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> + +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. diff --git a/node_modules/mocha/node_modules/commander/index.js b/node_modules/mocha/node_modules/commander/index.js new file mode 100644 index 0000000..8378d19 --- /dev/null +++ b/node_modules/mocha/node_modules/commander/index.js @@ -0,0 +1,876 @@ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter; +var spawn = require('child_process').spawn; +var path = require('path'); +var dirname = path.dirname; +var basename = path.basename; + +/** + * Expose the root command. + */ + +exports = module.exports = new Command; + +/** + * Expose `Command`. + */ + +exports.Command = Command; + +/** + * Expose `Option`. + */ + +exports.Option = Option; + +/** + * Initialize a new `Option` with the given `flags` and `description`. + * + * @param {String} flags + * @param {String} description + * @api public + */ + +function Option(flags, description) { + this.flags = flags; + this.required = ~flags.indexOf('<'); + this.optional = ~flags.indexOf('['); + this.bool = !~flags.indexOf('-no-'); + flags = flags.split(/[ ,|]+/); + if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); + this.long = flags.shift(); + this.description = description || ''; +} + +/** + * Return option name. + * + * @return {String} + * @api private + */ + +Option.prototype.name = function(){ + return this.long + .replace('--', '') + .replace('no-', ''); +}; + +/** + * Check if `arg` matches the short or long flag. + * + * @param {String} arg + * @return {Boolean} + * @api private + */ + +Option.prototype.is = function(arg){ + return arg == this.short + || arg == this.long; +}; + +/** + * Initialize a new `Command`. + * + * @param {String} name + * @api public + */ + +function Command(name) { + this.commands = []; + this.options = []; + this._execs = []; + this._args = []; + this._name = name; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ + +Command.prototype.__proto__ = EventEmitter.prototype; + +/** + * Add command `name`. + * + * The `.action()` callback is invoked when the + * command `name` is specified via __ARGV__, + * and the remaining arguments are applied to the + * function for access. + * + * When the `name` is "*" an un-matched command + * will be passed as the first arg, followed by + * the rest of __ARGV__ remaining. + * + * Examples: + * + * program + * .version('0.0.1') + * .option('-C, --chdir ', 'change the working directory') + * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') + * .option('-T, --no-tests', 'ignore test hook') + * + * program + * .command('setup') + * .description('run remote setup commands') + * .action(function(){ + * console.log('setup'); + * }); + * + * program + * .command('exec ') + * .description('run the given remote command') + * .action(function(cmd){ + * console.log('exec "%s"', cmd); + * }); + * + * program + * .command('*') + * .description('deploy the given env') + * .action(function(env){ + * console.log('deploying "%s"', env); + * }); + * + * program.parse(process.argv); + * + * @param {String} name + * @param {String} [desc] + * @return {Command} the new command + * @api public + */ + +Command.prototype.command = function(name, desc) { + var args = name.split(/ +/); + var cmd = new Command(args.shift()); + if (desc) cmd.description(desc); + if (desc) this.executables = true; + if (desc) this._execs[cmd._name] = true; + this.commands.push(cmd); + cmd.parseExpectedArgs(args); + cmd.parent = this; + if (desc) return this; + return cmd; +}; + +/** + * Add an implicit `help [cmd]` subcommand + * which invokes `--help` for the given command. + * + * @api private + */ + +Command.prototype.addImplicitHelpCommand = function() { + this.command('help [cmd]', 'display help for [cmd]'); +}; + +/** + * Parse expected `args`. + * + * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. + * + * @param {Array} args + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parseExpectedArgs = function(args){ + if (!args.length) return; + var self = this; + args.forEach(function(arg){ + switch (arg[0]) { + case '<': + self._args.push({ required: true, name: arg.slice(1, -1) }); + break; + case '[': + self._args.push({ required: false, name: arg.slice(1, -1) }); + break; + } + }); + return this; +}; + +/** + * Register callback `fn` for the command. + * + * Examples: + * + * program + * .command('help') + * .description('display verbose help') + * .action(function(){ + * // output help here + * }); + * + * @param {Function} fn + * @return {Command} for chaining + * @api public + */ + +Command.prototype.action = function(fn){ + var self = this; + var listener = function(args, unknown){ + // Parse any so-far unknown options + args = args || []; + unknown = unknown || []; + + var parsed = self.parseOptions(unknown); + + // Output help if necessary + outputHelpIfNecessary(self, parsed.unknown); + + // If there are still any unknown options, then we simply + // die, unless someone asked for help, in which case we give it + // to them, and then we die. + if (parsed.unknown.length > 0) { + self.unknownOption(parsed.unknown[0]); + } + + // Leftover arguments need to be pushed back. Fixes issue #56 + if (parsed.args.length) args = parsed.args.concat(args); + + self._args.forEach(function(arg, i){ + if (arg.required && null == args[i]) { + self.missingArgument(arg.name); + } + }); + + // Always append ourselves to the end of the arguments, + // to make sure we match the number of arguments the user + // expects + if (self._args.length) { + args[self._args.length] = self; + } else { + args.push(self); + } + + fn.apply(this, args); + }; + this.parent.on(this._name, listener); + if (this._alias) this.parent.on(this._alias, listener); + return this; +}; + +/** + * Define option with `flags`, `description` and optional + * coercion `fn`. + * + * The `flags` string should contain both the short and long flags, + * separated by comma, a pipe or space. The following are all valid + * all will output this way when `--help` is used. + * + * "-p, --pepper" + * "-p|--pepper" + * "-p --pepper" + * + * Examples: + * + * // simple boolean defaulting to false + * program.option('-p, --pepper', 'add pepper'); + * + * --pepper + * program.pepper + * // => Boolean + * + * // simple boolean defaulting to true + * program.option('-C, --no-cheese', 'remove cheese'); + * + * program.cheese + * // => true + * + * --no-cheese + * program.cheese + * // => false + * + * // required argument + * program.option('-C, --chdir ', 'change the working directory'); + * + * --chdir /tmp + * program.chdir + * // => "/tmp" + * + * // optional argument + * program.option('-c, --cheese [type]', 'add cheese [marble]'); + * + * @param {String} flags + * @param {String} description + * @param {Function|Mixed} fn or default + * @param {Mixed} defaultValue + * @return {Command} for chaining + * @api public + */ + +Command.prototype.option = function(flags, description, fn, defaultValue){ + var self = this + , option = new Option(flags, description) + , oname = option.name() + , name = camelcase(oname); + + // default as 3rd arg + if ('function' != typeof fn) defaultValue = fn, fn = null; + + // preassign default value only for --no-*, [optional], or + if (false == option.bool || option.optional || option.required) { + // when --no-* we make sure default is true + if (false == option.bool) defaultValue = true; + // preassign only if we have a default + if (undefined !== defaultValue) self[name] = defaultValue; + } + + // register the option + this.options.push(option); + + // when it's passed assign the value + // and conditionally invoke the callback + this.on(oname, function(val){ + // coercion + if (null !== val && fn) val = fn(val, undefined === self[name] ? defaultValue : self[name]); + + // unassigned or bool + if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) { + // if no value, bool true, and we have a default, then use it! + if (null == val) { + self[name] = option.bool + ? defaultValue || true + : false; + } else { + self[name] = val; + } + } else if (null !== val) { + // reassign + self[name] = val; + } + }); + + return this; +}; + +/** + * Parse `argv`, settings options and invoking commands when defined. + * + * @param {Array} argv + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parse = function(argv){ + // implicit help + if (this.executables) this.addImplicitHelpCommand(); + + // store raw args + this.rawArgs = argv; + + // guess name + this._name = this._name || basename(argv[1], '.js'); + + // process argv + var parsed = this.parseOptions(this.normalize(argv.slice(2))); + var args = this.args = parsed.args; + + var result = this.parseArgs(this.args, parsed.unknown); + + // executable sub-commands + var name = result.args[0]; + if (this._execs[name]) return this.executeSubCommand(argv, args, parsed.unknown); + + return result; +}; + +/** + * Execute a sub-command executable. + * + * @param {Array} argv + * @param {Array} args + * @param {Array} unknown + * @api private + */ + +Command.prototype.executeSubCommand = function(argv, args, unknown) { + args = args.concat(unknown); + + if (!args.length) this.help(); + if ('help' == args[0] && 1 == args.length) this.help(); + + // --help + if ('help' == args[0]) { + args[0] = args[1]; + args[1] = '--help'; + } + + // executable + var dir = dirname(argv[1]); + var bin = basename(argv[1], '.js') + '-' + args[0]; + + // check for ./ first + var local = path.join(dir, bin); + + // run it + args = args.slice(1); + args.unshift(local); + var proc = spawn('node', args, { stdio: 'inherit', customFds: [0, 1, 2] }); + proc.on('error', function(err){ + if (err.code == "ENOENT") { + console.error('\n %s(1) does not exist, try --help\n', bin); + } else if (err.code == "EACCES") { + console.error('\n %s(1) not executable. try chmod or run with root\n', bin); + } + }); + + this.runningCommand = proc; +}; + +/** + * Normalize `args`, splitting joined short flags. For example + * the arg "-abc" is equivalent to "-a -b -c". + * This also normalizes equal sign and splits "--abc=def" into "--abc def". + * + * @param {Array} args + * @return {Array} + * @api private + */ + +Command.prototype.normalize = function(args){ + var ret = [] + , arg + , lastOpt + , index; + + for (var i = 0, len = args.length; i < len; ++i) { + arg = args[i]; + i > 0 && (lastOpt = this.optionFor(args[i-1])); + + if (lastOpt && lastOpt.required) { + ret.push(arg); + } else if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) { + arg.slice(1).split('').forEach(function(c){ + ret.push('-' + c); + }); + } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) { + ret.push(arg.slice(0, index), arg.slice(index + 1)); + } else { + ret.push(arg); + } + } + + return ret; +}; + +/** + * Parse command `args`. + * + * When listener(s) are available those + * callbacks are invoked, otherwise the "*" + * event is emitted and those actions are invoked. + * + * @param {Array} args + * @return {Command} for chaining + * @api private + */ + +Command.prototype.parseArgs = function(args, unknown){ + var cmds = this.commands + , len = cmds.length + , name; + + if (args.length) { + name = args[0]; + if (this.listeners(name).length) { + this.emit(args.shift(), args, unknown); + } else { + this.emit('*', args); + } + } else { + outputHelpIfNecessary(this, unknown); + + // If there were no args and we have unknown options, + // then they are extraneous and we need to error. + if (unknown.length > 0) { + this.unknownOption(unknown[0]); + } + } + + return this; +}; + +/** + * Return an option matching `arg` if any. + * + * @param {String} arg + * @return {Option} + * @api private + */ + +Command.prototype.optionFor = function(arg){ + for (var i = 0, len = this.options.length; i < len; ++i) { + if (this.options[i].is(arg)) { + return this.options[i]; + } + } +}; + +/** + * Parse options from `argv` returning `argv` + * void of these options. + * + * @param {Array} argv + * @return {Array} + * @api public + */ + +Command.prototype.parseOptions = function(argv){ + var args = [] + , len = argv.length + , literal + , option + , arg; + + var unknownOptions = []; + + // parse options + for (var i = 0; i < len; ++i) { + arg = argv[i]; + + // literal args after -- + if ('--' == arg) { + literal = true; + continue; + } + + if (literal) { + args.push(arg); + continue; + } + + // find matching Option + option = this.optionFor(arg); + + // option is defined + if (option) { + // requires arg + if (option.required) { + arg = argv[++i]; + if (null == arg) return this.optionMissingArgument(option); + this.emit(option.name(), arg); + // optional arg + } else if (option.optional) { + arg = argv[i+1]; + if (null == arg || ('-' == arg[0] && '-' != arg)) { + arg = null; + } else { + ++i; + } + this.emit(option.name(), arg); + // bool + } else { + this.emit(option.name()); + } + continue; + } + + // looks like an option + if (arg.length > 1 && '-' == arg[0]) { + unknownOptions.push(arg); + + // If the next argument looks like it might be + // an argument for this option, we pass it on. + // If it isn't, then it'll simply be ignored + if (argv[i+1] && '-' != argv[i+1][0]) { + unknownOptions.push(argv[++i]); + } + continue; + } + + // arg + args.push(arg); + } + + return { args: args, unknown: unknownOptions }; +}; + +/** + * Argument `name` is missing. + * + * @param {String} name + * @api private + */ + +Command.prototype.missingArgument = function(name){ + console.error(); + console.error(" error: missing required argument `%s'", name); + console.error(); + process.exit(1); +}; + +/** + * `Option` is missing an argument, but received `flag` or nothing. + * + * @param {String} option + * @param {String} flag + * @api private + */ + +Command.prototype.optionMissingArgument = function(option, flag){ + console.error(); + if (flag) { + console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); + } else { + console.error(" error: option `%s' argument missing", option.flags); + } + console.error(); + process.exit(1); +}; + +/** + * Unknown option `flag`. + * + * @param {String} flag + * @api private + */ + +Command.prototype.unknownOption = function(flag){ + console.error(); + console.error(" error: unknown option `%s'", flag); + console.error(); + process.exit(1); +}; + + +/** + * Set the program version to `str`. + * + * This method auto-registers the "-V, --version" flag + * which will print the version number when passed. + * + * @param {String} str + * @param {String} flags + * @return {Command} for chaining + * @api public + */ + +Command.prototype.version = function(str, flags){ + if (0 == arguments.length) return this._version; + this._version = str; + flags = flags || '-V, --version'; + this.option(flags, 'output the version number'); + this.on('version', function(){ + console.log(str); + process.exit(0); + }); + return this; +}; + +/** + * Set the description `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.description = function(str){ + if (0 == arguments.length) return this._description; + this._description = str; + return this; +}; + +/** + * Set an alias for the command + * + * @param {String} alias + * @return {String|Command} + * @api public + */ + +Command.prototype.alias = function(alias){ + if (0 == arguments.length) return this._alias; + this._alias = alias; + return this; +}; + +/** + * Set / get the command usage `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.usage = function(str){ + var args = this._args.map(function(arg){ + return arg.required + ? '<' + arg.name + '>' + : '[' + arg.name + ']'; + }); + + var usage = '[options' + + (this.commands.length ? '] [command' : '') + + ']' + + (this._args.length ? ' ' + args : ''); + + if (0 == arguments.length) return this._usage || usage; + this._usage = str; + + return this; +}; + +/** + * Return the largest option length. + * + * @return {Number} + * @api private + */ + +Command.prototype.largestOptionLength = function(){ + return this.options.reduce(function(max, option){ + return Math.max(max, option.flags.length); + }, 0); +}; + +/** + * Return help for options. + * + * @return {String} + * @api private + */ + +Command.prototype.optionHelp = function(){ + var width = this.largestOptionLength(); + + // Prepend the help information + return [pad('-h, --help', width) + ' ' + 'output usage information'] + .concat(this.options.map(function(option){ + return pad(option.flags, width) + + ' ' + option.description; + })) + .join('\n'); +}; + +/** + * Return command help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.commandHelp = function(){ + if (!this.commands.length) return ''; + return [ + '' + , ' Commands:' + , '' + , this.commands.map(function(cmd){ + var args = cmd._args.map(function(arg){ + return arg.required + ? '<' + arg.name + '>' + : '[' + arg.name + ']'; + }).join(' '); + + return cmd._name + + (cmd._alias + ? '|' + cmd._alias + : '') + + (cmd.options.length + ? ' [options]' + : '') + ' ' + args + + (cmd.description() + ? '\n ' + cmd.description() + : '') + + '\n'; + }).join('\n').replace(/^/gm, ' ') + , '' + ].join('\n'); +}; + +/** + * Return program help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.helpInformation = function(){ + return [ + '' + , ' Usage: ' + this._name + + (this._alias + ? '|' + this._alias + : '') + + ' ' + this.usage() + , '' + this.commandHelp() + , ' Options:' + , '' + , '' + this.optionHelp().replace(/^/gm, ' ') + , '' + , '' + ].join('\n'); +}; + +/** + * Output help information for this command + * + * @api public + */ + +Command.prototype.outputHelp = function(){ + process.stdout.write(this.helpInformation()); + this.emit('--help'); +}; + +/** + * Output help information and exit. + * + * @api public + */ + +Command.prototype.help = function(){ + this.outputHelp(); + process.exit(); +}; + +/** + * Camel-case the given `flag` + * + * @param {String} flag + * @return {String} + * @api private + */ + +function camelcase(flag) { + return flag.split('-').reduce(function(str, word){ + return str + word[0].toUpperCase() + word.slice(1); + }); +} + +/** + * Pad `str` to `width`. + * + * @param {String} str + * @param {Number} width + * @return {String} + * @api private + */ + +function pad(str, width) { + var len = Math.max(0, width - str.length); + return str + Array(len + 1).join(' '); +} + +/** + * Output help information if necessary + * + * @param {Command} command to output help for + * @param {Array} array of options to search for -h or --help + * @api private + */ + +function outputHelpIfNecessary(cmd, options) { + options = options || []; + for (var i = 0; i < options.length; i++) { + if (options[i] == '--help' || options[i] == '-h') { + cmd.outputHelp(); + process.exit(0); + } + } +} diff --git a/node_modules/mocha/node_modules/commander/package.json b/node_modules/mocha/node_modules/commander/package.json new file mode 100644 index 0000000..75c1ca4 --- /dev/null +++ b/node_modules/mocha/node_modules/commander/package.json @@ -0,0 +1,71 @@ +{ + "name": "commander", + "version": "2.3.0", + "description": "the complete solution for node.js command-line programs", + "keywords": [ + "command", + "option", + "parser", + "prompt", + "stdin" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/visionmedia/commander.js.git" + }, + "devDependencies": { + "should": ">= 0.0.1" + }, + "scripts": { + "test": "make test" + }, + "main": "index", + "engines": { + "node": ">= 0.6.x" + }, + "files": [ + "index.js" + ], + "gitHead": "7e9f407ec03d4371a478c2fe417db4998ecb6169", + "bugs": { + "url": "https://github.com/visionmedia/commander.js/issues" + }, + "homepage": "https://github.com/visionmedia/commander.js", + "_id": "commander@2.3.0", + "_shasum": "fd430e889832ec353b9acd1de217c11cb3eef873", + "_from": "commander@2.3.0", + "_npmVersion": "1.4.21", + "_npmUser": { + "name": "somekittens", + "email": "rkoutnik@gmail.com" + }, + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "somekittens", + "email": "rkoutnik@gmail.com" + }, + { + "name": "zhiyelee", + "email": "zhiyelee@gmail.com" + }, + { + "name": "thethomaseffect", + "email": "thethomaseffect@gmail.com" + } + ], + "dist": { + "shasum": "fd430e889832ec353b9acd1de217c11cb3eef873", + "tarball": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mocha/node_modules/diff/README.md b/node_modules/mocha/node_modules/diff/README.md new file mode 100644 index 0000000..b867e19 --- /dev/null +++ b/node_modules/mocha/node_modules/diff/README.md @@ -0,0 +1,181 @@ +# jsdiff + +[![Build Status](https://secure.travis-ci.org/kpdecker/jsdiff.png)](http://travis-ci.org/kpdecker/jsdiff) + +A javascript text differencing implementation. + +Based on the algorithm 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). + +## Installation + + npm install diff + +or + + bower install jsdiff + +or + + git clone git://github.com/kpdecker/jsdiff.git + +## API + +* `JsDiff.diffChars(oldStr, newStr[, callback])` - diffs two blocks of text, comparing character by character. + + Returns a list of change objects (See below). + +* `JsDiff.diffWords(oldStr, newStr[, callback])` - diffs two blocks of text, comparing word by word, ignoring whitespace. + + Returns a list of change objects (See below). + +* `JsDiff.diffWordsWithSpace(oldStr, newStr[, callback])` - diffs two blocks of text, comparing word by word, treating whitespace as significant. + + Returns a list of change objects (See below). + +* `JsDiff.diffLines(oldStr, newStr[, callback])` - diffs two blocks of text, comparing line by line. + + Returns a list of change objects (See below). + +* `JsDiff.diffTrimmedLines(oldStr, newStr[, callback])` - diffs two blocks of text, comparing line by line, ignoring leading and trailing whitespace. + + Returns a list of change objects (See below). + +* `JsDiff.diffSentences(oldStr, newStr[, callback])` - diffs two blocks of text, comparing sentence by sentence. + + Returns a list of change objects (See below). + +* `JsDiff.diffCss(oldStr, newStr[, callback])` - diffs two blocks of text, comparing CSS tokens. + + Returns a list of change objects (See below). + +* `JsDiff.diffJson(oldObj, newObj[, callback])` - diffs two JSON objects, comparing the fields defined on each. The order of fields, etc does not matter in this comparison. + + Returns a list of change objects (See below). + +* `JsDiff.createTwoFilesPatch(oldFileName, newFileName, oldStr, newStr, oldHeader, newHeader)` - creates a unified diff patch. + + Parameters: + * `oldFileName` : String to be output in the filename section of the patch for the removals + * `newFileName` : String to be output in the filename section of the patch for the additions + * `oldStr` : Original string value + * `newStr` : New string value + * `oldHeader` : Additional information to include in the old file header + * `newHeader` : Additional information to include in thew new file header + +* `JsDiff.createPatch(fileName, oldStr, newStr, oldHeader, newHeader)` - creates a unified diff patch. + + Just like JsDiff.createTwoFilesPatch, but with oldFileName being equal to newFileName. + +* `JsDiff.applyPatch(oldStr, diffStr)` - applies a unified diff patch. + + Return a string containing new version of provided data. + +* `convertChangesToXML(changes)` - converts a list of changes to a serialized XML format + + +All methods above which accept the optional callback method will run in sync mode when that parameter is omitted and in async mode when supplied. This allows for larger diffs without blocking the event loop. + +### Change Objects +Many of the methods above return change objects. These objects are consist of the following fields: + +* `value`: Text content +* `added`: True if the value was inserted into the new string +* `removed`: True of the value was removed from the old string + +Note that some cases may omit a particular flag field. Comparison on the flag fields should always be done in a truthy or falsy manner. + +## Examples + +Basic example in Node + +```js +require('colors') +var jsdiff = require('diff'); + +var one = 'beep boop'; +var other = 'beep boob blah'; + +var diff = jsdiff.diffChars(one, other); + +diff.forEach(function(part){ + // green for additions, red for deletions + // grey for common parts + var color = part.added ? 'green' : + part.removed ? 'red' : 'grey'; + process.stderr.write(part.value[color]); +}); + +console.log() +``` +Running the above program should yield + +Node Example + +Basic example in a web page + +```html +
    
    +
    +
    +```
    +
    +Open the above .html file in a browser and you should see
    +
    +Node Example
    +
    +**[Full online demo](http://kpdecker.github.com/jsdiff)**
    +
    +## License
    +
    +Software License Agreement (BSD License)
    +
    +Copyright (c) 2009-2011, Kevin Decker kpdecker@gmail.com
    +
    +All rights reserved.
    +
    +Redistribution and use of this software in source and binary forms, with or without modification,
    +are permitted provided that the following conditions are met:
    +
    +* Redistributions of source code must retain the above
    +  copyright notice, this list of conditions and the
    +  following disclaimer.
    +
    +* Redistributions in binary form must reproduce the above
    +  copyright notice, this list of conditions and the
    +  following disclaimer in the documentation and/or other
    +  materials provided with the distribution.
    +
    +* Neither the name of Kevin Decker nor the names of its
    +  contributors may be used to endorse or promote products
    +  derived from this software without specific prior
    +  written permission.
    +
    +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
    +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
    +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    +
    +
    +[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/kpdecker/jsdiff/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
    diff --git a/node_modules/mocha/node_modules/diff/diff.js b/node_modules/mocha/node_modules/diff/diff.js
    new file mode 100644
    index 0000000..421854a
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/diff/diff.js
    @@ -0,0 +1,619 @@
    +/* See LICENSE file for terms of use */
    +
    +/*
    + * 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);
    +    }
    +
    +    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 n;
    +  }
    +
    +  // 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 || [];
    +
    +    var i;
    +
    +    for (i = 0; i < stack.length; i += 1) {
    +      if (stack[i] === obj) {
    +        return replacementStack[i];
    +      }
    +    }
    +
    +    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();
    +    } else {
    +      canonicalizedObj = obj;
    +    }
    +    return canonicalizedObj;
    +  }
    +
    +  function buildValues(components, newString, oldString, useLongestToken) {
    +    var componentPos = 0,
    +        componentLen = components.length,
    +        newPos = 0,
    +        oldPos = 0;
    +
    +    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;
    +          });
    +
    +          component.value = value.join('');
    +        } else {
    +          component.value = newString.slice(newPos, newPos + component.count).join('');
    +        }
    +        newPos += component.count;
    +
    +        // Common case
    +        if (!component.added) {
    +          oldPos += component.count;
    +        }
    +      } else {
    +        component.value = oldString.slice(oldPos, oldPos + component.count).join('');
    +        oldPos += component.count;
    +
    +        // 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;
    +        }
    +      }
    +    }
    +
    +    return components;
    +  }
    +
    +  function Diff(ignoreWhitespace) {
    +    this.ignoreWhitespace = ignoreWhitespace;
    +  }
    +  Diff.prototype = {
    +    diff: function(oldString, newString, callback) {
    +      var self = this;
    +
    +      function done(value) {
    +        if (callback) {
    +          setTimeout(function() { callback(undefined, value); }, 0);
    +          return true;
    +        } else {
    +          return value;
    +        }
    +      }
    +
    +      // 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 }]);
    +      }
    +
    +      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('')}]);
    +      }
    +
    +      // 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;
    +          }
    +
    +          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;
    +          }
    +
    +          // 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);
    +          }
    +
    +          oldPos = self.extractCommon(basePath, newString, oldString, diagonalPath);
    +
    +          // 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;
    +          }
    +        }
    +
    +        editLength++;
    +      }
    +
    +      // 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 (!execEditLength()) {
    +              exec();
    +            }
    +          }, 0);
    +        }());
    +      } else {
    +        while (editLength <= maxEditLength) {
    +          var ret = execEditLength();
    +          if (ret) {
    +            return ret;
    +          }
    +        }
    +      }
    +    },
    +
    +    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,
    +
    +          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});
    +      }
    +
    +      basePath.newPos = newPos;
    +      return oldPos;
    +    },
    +
    +    equals: function(left, right) {
    +      var reWhitespace = /\S/;
    +      return left === right || (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right));
    +    },
    +    tokenize: function(value) {
    +      return value.split('');
    +    }
    +  };
    +
    +  var CharDiff = new Diff();
    +
    +  var WordDiff = new Diff(true);
    +  var WordWithSpaceDiff = new Diff();
    +  WordDiff.tokenize = WordWithSpaceDiff.tokenize = function(value) {
    +    return removeEmpty(value.split(/(\s+|\b)/));
    +  };
    +
    +  var CssDiff = new Diff(true);
    +  CssDiff.tokenize = function(value) {
    +    return removeEmpty(value.split(/([{}:;,]|\s+)/));
    +  };
    +
    +  var LineDiff = new Diff();
    +
    +  var TrimmedLineDiff = new Diff();
    +  TrimmedLineDiff.ignoreTrim = true;
    +
    +  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];
    +
    +      // 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 retLines;
    +  };
    +
    +  var PatchDiff = new Diff();
    +  PatchDiff.tokenize = function(value) {
    +    var ret = [],
    +        linesAndNewlines = value.split(/(\n|\r\n)/);
    +
    +    // Ignore the final empty token that occurs if the string ends with a new line
    +    if (!linesAndNewlines[linesAndNewlines.length - 1]) {
    +      linesAndNewlines.pop();
    +    }
    +
    +    // Merge the content and line separators into single tokens
    +    for (var i = 0; i < linesAndNewlines.length; i++) {
    +      var line = linesAndNewlines[i];
    +
    +      if (i % 2) {
    +        ret[ret.length - 1] += line;
    +      } else {
    +        ret.push(line);
    +      }
    +    }
    +    return ret;
    +  };
    +
    +  var SentenceDiff = new Diff();
    +  SentenceDiff.tokenize = function(value) {
    +    return removeEmpty(value.split(/(\S.+?[.!?])(?=\s+|$)/));
    +  };
    +
    +  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,
    +
    +    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); },
    +
    +    diffSentences: function(oldStr, newStr, callback) { return SentenceDiff.diff(oldStr, newStr, callback); },
    +
    +    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 = [];
    +
    +      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));
    +
    +      var diff = PatchDiff.diff(oldStr, newStr);
    +      diff.push({value: '', lines: []});   // Append an empty value to make cleanup easier
    +
    +      // 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;
    +
    +        // 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 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 (current.added || current.removed) {
    +          // If we have previous context, start with that
    +          if (!oldRangeStart) {
    +            var prev = diff[i - 1];
    +            oldRangeStart = oldLine;
    +            newRangeStart = newLine;
    +
    +            if (prev) {
    +              curRange = contextLines(prev.lines.slice(-4));
    +              oldRangeStart -= curRange.length;
    +              newRangeStart -= curRange.length;
    +            }
    +          }
    +
    +          // Output our changes
    +          curRange.push.apply(curRange, map(lines, function(entry) {
    +            return (current.added ? '+' : '-') + entry;
    +          }));
    +          eofNL(curRange, i, current);
    +
    +          // 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);
    +              }
    +
    +              oldRangeStart = 0;
    +              newRangeStart = 0;
    +              curRange = [];
    +            }
    +          }
    +          oldLine += lines.length;
    +          newLine += lines.length;
    +        }
    +      }
    +
    +      return ret.join('\n') + '\n';
    +    },
    +
    +    createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
    +      return JsDiff.createTwoFilesPatch(fileName, fileName, oldStr, newStr, oldHeader, newHeader);
    +    },
    +
    +    applyPatch: function(oldStr, uniDiff) {
    +      var diffstr = uniDiff.split('\n'),
    +          hunks = [],
    +          i = 0,
    +          remEOFNL = false,
    +          addEOFNL = false;
    +
    +      // Skip to the first change hunk
    +      while (i < diffstr.length && !(/^@@/.test(diffstr[i]))) {
    +        i++;
    +      }
    +
    +      // 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;
    +          }
    +        }
    +      }
    +
    +      // 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));
    +      }
    +
    +      // Handle EOFNL insertion/removal
    +      if (remEOFNL) {
    +        while (!lines[lines.length - 1]) {
    +          lines.pop();
    +        }
    +      } else if (addEOFNL) {
    +        lines.push('');
    +      }
    +      return lines.join('\n');
    +    },
    +
    +    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('');
    +        }
    +
    +        ret.push(escapeHTML(change.value));
    +
    +        if (change.added) {
    +          ret.push('');
    +        } else if (change.removed) {
    +          ret.push('');
    +        }
    +      }
    +      return ret.join('');
    +    },
    +
    +    // 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;
    +        }
    +
    +        ret.push([operation, change.value]);
    +      }
    +      return ret;
    +    },
    +
    +    canonicalize: canonicalize
    +  };
    +
    +  /*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));
    diff --git a/node_modules/mocha/node_modules/diff/package.json b/node_modules/mocha/node_modules/diff/package.json
    new file mode 100644
    index 0000000..cc2af94
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/diff/package.json
    @@ -0,0 +1,64 @@
    +{
    +  "name": "diff",
    +  "version": "1.4.0",
    +  "description": "A javascript text diff implementation.",
    +  "keywords": [
    +    "diff",
    +    "javascript"
    +  ],
    +  "maintainers": [
    +    {
    +      "name": "kpdecker",
    +      "email": "kpdecker@gmail.com"
    +    }
    +  ],
    +  "bugs": {
    +    "url": "http://github.com/kpdecker/jsdiff/issues",
    +    "email": "kpdecker@gmail.com"
    +  },
    +  "licenses": [
    +    {
    +      "type": "BSD",
    +      "url": "http://github.com/kpdecker/jsdiff/blob/master/LICENSE"
    +    }
    +  ],
    +  "repository": {
    +    "type": "git",
    +    "url": "git://github.com/kpdecker/jsdiff.git"
    +  },
    +  "engines": {
    +    "node": ">=0.3.1"
    +  },
    +  "main": "./diff",
    +  "scripts": {
    +    "test": "istanbul cover node_modules/.bin/_mocha test/*.js && istanbul check-coverage --statements 100 --functions 100 --branches 100 --lines 100 coverage/coverage.json"
    +  },
    +  "dependencies": {},
    +  "devDependencies": {
    +    "colors": "^1.1.0",
    +    "istanbul": "^0.3.2",
    +    "mocha": "^2.2.4",
    +    "should": "^6.0.1"
    +  },
    +  "optionalDependencies": {},
    +  "files": [
    +    "diff.js"
    +  ],
    +  "gitHead": "27a750e9116e6ade6303bc24a9be72f6845e00ed",
    +  "homepage": "https://github.com/kpdecker/jsdiff",
    +  "_id": "diff@1.4.0",
    +  "_shasum": "7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf",
    +  "_from": "diff@1.4.0",
    +  "_npmVersion": "1.4.28",
    +  "_npmUser": {
    +    "name": "kpdecker",
    +    "email": "kpdecker@gmail.com"
    +  },
    +  "dist": {
    +    "shasum": "7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf",
    +    "tarball": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz"
    +  },
    +  "directories": {},
    +  "_resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/escape-string-regexp/index.js b/node_modules/mocha/node_modules/escape-string-regexp/index.js
    new file mode 100644
    index 0000000..ac6572c
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/escape-string-regexp/index.js
    @@ -0,0 +1,11 @@
    +'use strict';
    +
    +var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
    +
    +module.exports = function (str) {
    +	if (typeof str !== 'string') {
    +		throw new TypeError('Expected a string');
    +	}
    +
    +	return str.replace(matchOperatorsRe,  '\\$&');
    +};
    diff --git a/node_modules/mocha/node_modules/escape-string-regexp/package.json b/node_modules/mocha/node_modules/escape-string-regexp/package.json
    new file mode 100644
    index 0000000..28ad1f9
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/escape-string-regexp/package.json
    @@ -0,0 +1,69 @@
    +{
    +  "name": "escape-string-regexp",
    +  "version": "1.0.2",
    +  "description": "Escape RegExp special characters",
    +  "license": "MIT",
    +  "repository": {
    +    "type": "git",
    +    "url": "git+https://github.com/sindresorhus/escape-string-regexp.git"
    +  },
    +  "author": {
    +    "name": "Sindre Sorhus",
    +    "email": "sindresorhus@gmail.com",
    +    "url": "http://sindresorhus.com"
    +  },
    +  "engines": {
    +    "node": ">=0.8.0"
    +  },
    +  "scripts": {
    +    "test": "mocha"
    +  },
    +  "files": [
    +    "index.js"
    +  ],
    +  "keywords": [
    +    "regex",
    +    "regexp",
    +    "re",
    +    "regular",
    +    "expression",
    +    "escape",
    +    "string",
    +    "str",
    +    "special",
    +    "characters"
    +  ],
    +  "devDependencies": {
    +    "mocha": "*"
    +  },
    +  "gitHead": "0587ee0ee03ea3fcbfa3c15cf67b47f214e20987",
    +  "bugs": {
    +    "url": "https://github.com/sindresorhus/escape-string-regexp/issues"
    +  },
    +  "homepage": "https://github.com/sindresorhus/escape-string-regexp",
    +  "_id": "escape-string-regexp@1.0.2",
    +  "_shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1",
    +  "_from": "escape-string-regexp@1.0.2",
    +  "_npmVersion": "1.4.23",
    +  "_npmUser": {
    +    "name": "jbnicolai",
    +    "email": "jappelman@xebia.com"
    +  },
    +  "maintainers": [
    +    {
    +      "name": "sindresorhus",
    +      "email": "sindresorhus@gmail.com"
    +    },
    +    {
    +      "name": "jbnicolai",
    +      "email": "jappelman@xebia.com"
    +    }
    +  ],
    +  "dist": {
    +    "shasum": "4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1",
    +    "tarball": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz"
    +  },
    +  "directories": {},
    +  "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/escape-string-regexp/readme.md b/node_modules/mocha/node_modules/escape-string-regexp/readme.md
    new file mode 100644
    index 0000000..808a963
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/escape-string-regexp/readme.md
    @@ -0,0 +1,27 @@
    +# escape-string-regexp [![Build Status](https://travis-ci.org/sindresorhus/escape-string-regexp.svg?branch=master)](https://travis-ci.org/sindresorhus/escape-string-regexp)
    +
    +> Escape RegExp special characters
    +
    +
    +## Install
    +
    +```sh
    +$ npm install --save escape-string-regexp
    +```
    +
    +
    +## Usage
    +
    +```js
    +var escapeStringRegexp = require('escape-string-regexp');
    +
    +var escapedString = escapeStringRegexp('how much $ for a unicorn?');
    +//=> how much \$ for a unicorn\?
    +
    +new RegExp(escapedString);
    +```
    +
    +
    +## License
    +
    +MIT © [Sindre Sorhus](http://sindresorhus.com)
    diff --git a/node_modules/mocha/node_modules/glob/.npmignore b/node_modules/mocha/node_modules/glob/.npmignore
    new file mode 100644
    index 0000000..2af4b71
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/.npmignore
    @@ -0,0 +1,2 @@
    +.*.swp
    +test/a/
    diff --git a/node_modules/mocha/node_modules/glob/.travis.yml b/node_modules/mocha/node_modules/glob/.travis.yml
    new file mode 100644
    index 0000000..baa0031
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/.travis.yml
    @@ -0,0 +1,3 @@
    +language: node_js
    +node_js:
    +  - 0.8
    diff --git a/node_modules/mocha/node_modules/glob/LICENSE b/node_modules/mocha/node_modules/glob/LICENSE
    new file mode 100644
    index 0000000..0c44ae7
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/LICENSE
    @@ -0,0 +1,27 @@
    +Copyright (c) Isaac Z. Schlueter ("Author")
    +All rights reserved.
    +
    +The BSD License
    +
    +Redistribution and use in source and binary forms, with or without
    +modification, are permitted provided that the following conditions
    +are met:
    +
    +1. Redistributions of source code must retain the above copyright
    +   notice, this list of conditions and the following disclaimer.
    +
    +2. Redistributions in binary form must reproduce the above copyright
    +   notice, this list of conditions and the following disclaimer in the
    +   documentation and/or other materials provided with the distribution.
    +
    +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
    +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    +PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
    +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
    +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
    +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
    +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    diff --git a/node_modules/mocha/node_modules/glob/README.md b/node_modules/mocha/node_modules/glob/README.md
    new file mode 100644
    index 0000000..cc69164
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/README.md
    @@ -0,0 +1,250 @@
    +# Glob
    +
    +Match files using the patterns the shell uses, like stars and stuff.
    +
    +This is a glob implementation in JavaScript.  It uses the `minimatch`
    +library to do its matching.
    +
    +## Attention: node-glob users!
    +
    +The API has changed dramatically between 2.x and 3.x. This library is
    +now 100% JavaScript, and the integer flags have been replaced with an
    +options object.
    +
    +Also, there's an event emitter class, proper tests, and all the other
    +things you've come to expect from node modules.
    +
    +And best of all, no compilation!
    +
    +## Usage
    +
    +```javascript
    +var glob = require("glob")
    +
    +// options is optional
    +glob("**/*.js", options, function (er, files) {
    +  // files is an array of filenames.
    +  // If the `nonull` option is set, and nothing
    +  // was found, then files is ["**/*.js"]
    +  // er is an error object or null.
    +})
    +```
    +
    +## Features
    +
    +Please see the [minimatch
    +documentation](https://github.com/isaacs/minimatch) for more details.
    +
    +Supports these glob features:
    +
    +* Brace Expansion
    +* Extended glob matching
    +* "Globstar" `**` matching
    +
    +See:
    +
    +* `man sh`
    +* `man bash`
    +* `man 3 fnmatch`
    +* `man 5 gitignore`
    +* [minimatch documentation](https://github.com/isaacs/minimatch)
    +
    +## glob(pattern, [options], cb)
    +
    +* `pattern` {String} Pattern to be matched
    +* `options` {Object}
    +* `cb` {Function}
    +  * `err` {Error | null}
    +  * `matches` {Array} filenames found matching the pattern
    +
    +Perform an asynchronous glob search.
    +
    +## glob.sync(pattern, [options])
    +
    +* `pattern` {String} Pattern to be matched
    +* `options` {Object}
    +* return: {Array} filenames found matching the pattern
    +
    +Perform a synchronous glob search.
    +
    +## Class: glob.Glob
    +
    +Create a Glob object by instanting the `glob.Glob` class.
    +
    +```javascript
    +var Glob = require("glob").Glob
    +var mg = new Glob(pattern, options, cb)
    +```
    +
    +It's an EventEmitter, and starts walking the filesystem to find matches
    +immediately.
    +
    +### new glob.Glob(pattern, [options], [cb])
    +
    +* `pattern` {String} pattern to search for
    +* `options` {Object}
    +* `cb` {Function} Called when an error occurs, or matches are found
    +  * `err` {Error | null}
    +  * `matches` {Array} filenames found matching the pattern
    +
    +Note that if the `sync` flag is set in the options, then matches will
    +be immediately available on the `g.found` member.
    +
    +### Properties
    +
    +* `minimatch` The minimatch object that the glob uses.
    +* `options` The options object passed in.
    +* `error` The error encountered.  When an error is encountered, the
    +  glob object is in an undefined state, and should be discarded.
    +* `aborted` Boolean which is set to true when calling `abort()`.  There
    +  is no way at this time to continue a glob search after aborting, but
    +  you can re-use the statCache to avoid having to duplicate syscalls.
    +* `statCache` Collection of all the stat results the glob search
    +  performed.
    +* `cache` Convenience object.  Each field has the following possible
    +  values:
    +  * `false` - Path does not exist
    +  * `true` - Path exists
    +  * `1` - Path exists, and is not a directory
    +  * `2` - Path exists, and is a directory
    +  * `[file, entries, ...]` - Path exists, is a directory, and the
    +    array value is the results of `fs.readdir`
    +
    +### Events
    +
    +* `end` When the matching is finished, this is emitted with all the
    +  matches found.  If the `nonull` option is set, and no match was found,
    +  then the `matches` list contains the original pattern.  The matches
    +  are sorted, unless the `nosort` flag is set.
    +* `match` Every time a match is found, this is emitted with the matched.
    +* `error` Emitted when an unexpected error is encountered, or whenever
    +  any fs error occurs if `options.strict` is set.
    +* `abort` When `abort()` is called, this event is raised.
    +
    +### Methods
    +
    +* `abort` Stop the search.
    +
    +### Options
    +
    +All the options that can be passed to Minimatch can also be passed to
    +Glob to change pattern matching behavior.  Also, some have been added,
    +or have glob-specific ramifications.
    +
    +All options are false by default, unless otherwise noted.
    +
    +All options are added to the glob object, as well.
    +
    +* `cwd` The current working directory in which to search.  Defaults
    +  to `process.cwd()`.
    +* `root` The place where patterns starting with `/` will be mounted
    +  onto.  Defaults to `path.resolve(options.cwd, "/")` (`/` on Unix
    +  systems, and `C:\` or some such on Windows.)
    +* `dot` Include `.dot` files in normal matches and `globstar` matches.
    +  Note that an explicit dot in a portion of the pattern will always
    +  match dot files.
    +* `nomount` By default, a pattern starting with a forward-slash will be
    +  "mounted" onto the root setting, so that a valid filesystem path is
    +  returned.  Set this flag to disable that behavior.
    +* `mark` Add a `/` character to directory matches.  Note that this
    +  requires additional stat calls.
    +* `nosort` Don't sort the results.
    +* `stat` Set to true to stat *all* results.  This reduces performance
    +  somewhat, and is completely unnecessary, unless `readdir` is presumed
    +  to be an untrustworthy indicator of file existence.  It will cause
    +  ELOOP to be triggered one level sooner in the case of cyclical
    +  symbolic links.
    +* `silent` When an unusual error is encountered
    +  when attempting to read a directory, a warning will be printed to
    +  stderr.  Set the `silent` option to true to suppress these warnings.
    +* `strict` When an unusual error is encountered
    +  when attempting to read a directory, the process will just continue on
    +  in search of other matches.  Set the `strict` option to raise an error
    +  in these cases.
    +* `cache` See `cache` property above.  Pass in a previously generated
    +  cache object to save some fs calls.
    +* `statCache` A cache of results of filesystem information, to prevent
    +  unnecessary stat calls.  While it should not normally be necessary to
    +  set this, you may pass the statCache from one glob() call to the
    +  options object of another, if you know that the filesystem will not
    +  change between calls.  (See "Race Conditions" below.)
    +* `sync` Perform a synchronous glob search.
    +* `nounique` In some cases, brace-expanded patterns can result in the
    +  same file showing up multiple times in the result set.  By default,
    +  this implementation prevents duplicates in the result set.
    +  Set this flag to disable that behavior.
    +* `nonull` Set to never return an empty set, instead returning a set
    +  containing the pattern itself.  This is the default in glob(3).
    +* `nocase` Perform a case-insensitive match.  Note that case-insensitive
    +  filesystems will sometimes result in glob returning results that are
    +  case-insensitively matched anyway, since readdir and stat will not
    +  raise an error.
    +* `debug` Set to enable debug logging in minimatch and glob.
    +* `globDebug` Set to enable debug logging in glob, but not minimatch.
    +
    +## Comparisons to other fnmatch/glob implementations
    +
    +While strict compliance with the existing standards is a worthwhile
    +goal, some discrepancies exist between node-glob and other
    +implementations, and are intentional.
    +
    +If the pattern starts with a `!` character, then it is negated.  Set the
    +`nonegate` flag to suppress this behavior, and treat leading `!`
    +characters normally.  This is perhaps relevant if you wish to start the
    +pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
    +characters at the start of a pattern will negate the pattern multiple
    +times.
    +
    +If a pattern starts with `#`, then it is treated as a comment, and
    +will not match anything.  Use `\#` to match a literal `#` at the
    +start of a line, or set the `nocomment` flag to suppress this behavior.
    +
    +The double-star character `**` is supported by default, unless the
    +`noglobstar` flag is set.  This is supported in the manner of bsdglob
    +and bash 4.1, where `**` only has special significance if it is the only
    +thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
    +`a/**b` will not.
    +
    +If an escaped pattern has no matches, and the `nonull` flag is set,
    +then glob returns the pattern as-provided, rather than
    +interpreting the character escapes.  For example,
    +`glob.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
    +`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
    +that it does not resolve escaped pattern characters.
    +
    +If brace expansion is not disabled, then it is performed before any
    +other interpretation of the glob pattern.  Thus, a pattern like
    +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
    +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
    +checked for validity.  Since those two are valid, matching proceeds.
    +
    +## Windows
    +
    +**Please only use forward-slashes in glob expressions.**
    +
    +Though windows uses either `/` or `\` as its path separator, only `/`
    +characters are used by this glob implementation.  You must use
    +forward-slashes **only** in glob expressions.  Back-slashes will always
    +be interpreted as escape characters, not path separators.
    +
    +Results from absolute patterns such as `/foo/*` are mounted onto the
    +root setting using `path.join`.  On windows, this will by default result
    +in `/foo/*` matching `C:\foo\bar.txt`.
    +
    +## Race Conditions
    +
    +Glob searching, by its very nature, is susceptible to race conditions,
    +since it relies on directory walking and such.
    +
    +As a result, it is possible that a file that exists when glob looks for
    +it may have been deleted or modified by the time it returns the result.
    +
    +As part of its internal implementation, this program caches all stat
    +and readdir calls that it makes, in order to cut down on system
    +overhead.  However, this also makes it even more susceptible to races,
    +especially if the cache or statCache objects are reused between glob
    +calls.
    +
    +Users are thus advised not to use a glob result as a guarantee of
    +filesystem state in the face of rapid changes.  For the vast majority
    +of operations, this is never a problem.
    diff --git a/node_modules/mocha/node_modules/glob/examples/g.js b/node_modules/mocha/node_modules/glob/examples/g.js
    new file mode 100644
    index 0000000..be122df
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/examples/g.js
    @@ -0,0 +1,9 @@
    +var Glob = require("../").Glob
    +
    +var pattern = "test/a/**/[cg]/../[cg]"
    +console.log(pattern)
    +
    +var mg = new Glob(pattern, {mark: true, sync:true}, function (er, matches) {
    +  console.log("matches", matches)
    +})
    +console.log("after")
    diff --git a/node_modules/mocha/node_modules/glob/examples/usr-local.js b/node_modules/mocha/node_modules/glob/examples/usr-local.js
    new file mode 100644
    index 0000000..327a425
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/examples/usr-local.js
    @@ -0,0 +1,9 @@
    +var Glob = require("../").Glob
    +
    +var pattern = "{./*/*,/*,/usr/local/*}"
    +console.log(pattern)
    +
    +var mg = new Glob(pattern, {mark: true}, function (er, matches) {
    +  console.log("matches", matches)
    +})
    +console.log("after")
    diff --git a/node_modules/mocha/node_modules/glob/glob.js b/node_modules/mocha/node_modules/glob/glob.js
    new file mode 100644
    index 0000000..f646c44
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/glob.js
    @@ -0,0 +1,728 @@
    +// Approach:
    +//
    +// 1. Get the minimatch set
    +// 2. For each pattern in the set, PROCESS(pattern)
    +// 3. Store matches per-set, then uniq them
    +//
    +// PROCESS(pattern)
    +// Get the first [n] items from pattern that are all strings
    +// Join these together.  This is PREFIX.
    +//   If there is no more remaining, then stat(PREFIX) and
    +//   add to matches if it succeeds.  END.
    +// readdir(PREFIX) as ENTRIES
    +//   If fails, END
    +//   If pattern[n] is GLOBSTAR
    +//     // handle the case where the globstar match is empty
    +//     // by pruning it out, and testing the resulting pattern
    +//     PROCESS(pattern[0..n] + pattern[n+1 .. $])
    +//     // handle other cases.
    +//     for ENTRY in ENTRIES (not dotfiles)
    +//       // attach globstar + tail onto the entry
    +//       PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
    +//
    +//   else // not globstar
    +//     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
    +//       Test ENTRY against pattern[n]
    +//       If fails, continue
    +//       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
    +//
    +// Caveat:
    +//   Cache all stats and readdirs results to minimize syscall.  Since all
    +//   we ever care about is existence and directory-ness, we can just keep
    +//   `true` for files, and [children,...] for directories, or `false` for
    +//   things that don't exist.
    +
    +
    +
    +module.exports = glob
    +
    +var fs = require("fs")
    +, minimatch = require("minimatch")
    +, Minimatch = minimatch.Minimatch
    +, inherits = require("inherits")
    +, EE = require("events").EventEmitter
    +, path = require("path")
    +, isDir = {}
    +, assert = require("assert").ok
    +
    +function glob (pattern, options, cb) {
    +  if (typeof options === "function") cb = options, options = {}
    +  if (!options) options = {}
    +
    +  if (typeof options === "number") {
    +    deprecated()
    +    return
    +  }
    +
    +  var g = new Glob(pattern, options, cb)
    +  return g.sync ? g.found : g
    +}
    +
    +glob.fnmatch = deprecated
    +
    +function deprecated () {
    +  throw new Error("glob's interface has changed. Please see the docs.")
    +}
    +
    +glob.sync = globSync
    +function globSync (pattern, options) {
    +  if (typeof options === "number") {
    +    deprecated()
    +    return
    +  }
    +
    +  options = options || {}
    +  options.sync = true
    +  return glob(pattern, options)
    +}
    +
    +this._processingEmitQueue = false
    +
    +glob.Glob = Glob
    +inherits(Glob, EE)
    +function Glob (pattern, options, cb) {
    +  if (!(this instanceof Glob)) {
    +    return new Glob(pattern, options, cb)
    +  }
    +
    +  if (typeof options === "function") {
    +    cb = options
    +    options = null
    +  }
    +
    +  if (typeof cb === "function") {
    +    this.on("error", cb)
    +    this.on("end", function (matches) {
    +      cb(null, matches)
    +    })
    +  }
    +
    +  options = options || {}
    +
    +  this._endEmitted = false
    +  this.EOF = {}
    +  this._emitQueue = []
    +
    +  this.paused = false
    +  this._processingEmitQueue = false
    +
    +  this.maxDepth = options.maxDepth || 1000
    +  this.maxLength = options.maxLength || Infinity
    +  this.cache = options.cache || {}
    +  this.statCache = options.statCache || {}
    +
    +  this.changedCwd = false
    +  var cwd = process.cwd()
    +  if (!options.hasOwnProperty("cwd")) this.cwd = cwd
    +  else {
    +    this.cwd = options.cwd
    +    this.changedCwd = path.resolve(options.cwd) !== cwd
    +  }
    +
    +  this.root = options.root || path.resolve(this.cwd, "/")
    +  this.root = path.resolve(this.root)
    +  if (process.platform === "win32")
    +    this.root = this.root.replace(/\\/g, "/")
    +
    +  this.nomount = !!options.nomount
    +
    +  if (!pattern) {
    +    throw new Error("must provide pattern")
    +  }
    +
    +  // base-matching: just use globstar for that.
    +  if (options.matchBase && -1 === pattern.indexOf("/")) {
    +    if (options.noglobstar) {
    +      throw new Error("base matching requires globstar")
    +    }
    +    pattern = "**/" + pattern
    +  }
    +
    +  this.strict = options.strict !== false
    +  this.dot = !!options.dot
    +  this.mark = !!options.mark
    +  this.sync = !!options.sync
    +  this.nounique = !!options.nounique
    +  this.nonull = !!options.nonull
    +  this.nosort = !!options.nosort
    +  this.nocase = !!options.nocase
    +  this.stat = !!options.stat
    +
    +  this.debug = !!options.debug || !!options.globDebug
    +  if (this.debug)
    +    this.log = console.error
    +
    +  this.silent = !!options.silent
    +
    +  var mm = this.minimatch = new Minimatch(pattern, options)
    +  this.options = mm.options
    +  pattern = this.pattern = mm.pattern
    +
    +  this.error = null
    +  this.aborted = false
    +
    +  // list of all the patterns that ** has resolved do, so
    +  // we can avoid visiting multiple times.
    +  this._globstars = {}
    +
    +  EE.call(this)
    +
    +  // process each pattern in the minimatch set
    +  var n = this.minimatch.set.length
    +
    +  // The matches are stored as {: true,...} so that
    +  // duplicates are automagically pruned.
    +  // Later, we do an Object.keys() on these.
    +  // Keep them as a list so we can fill in when nonull is set.
    +  this.matches = new Array(n)
    +
    +  this.minimatch.set.forEach(iterator.bind(this))
    +  function iterator (pattern, i, set) {
    +    this._process(pattern, 0, i, function (er) {
    +      if (er) this.emit("error", er)
    +      if (-- n <= 0) this._finish()
    +    })
    +  }
    +}
    +
    +Glob.prototype.log = function () {}
    +
    +Glob.prototype._finish = function () {
    +  assert(this instanceof Glob)
    +
    +  var nou = this.nounique
    +  , all = nou ? [] : {}
    +
    +  for (var i = 0, l = this.matches.length; i < l; i ++) {
    +    var matches = this.matches[i]
    +    this.log("matches[%d] =", i, matches)
    +    // do like the shell, and spit out the literal glob
    +    if (!matches) {
    +      if (this.nonull) {
    +        var literal = this.minimatch.globSet[i]
    +        if (nou) all.push(literal)
    +        else all[literal] = true
    +      }
    +    } else {
    +      // had matches
    +      var m = Object.keys(matches)
    +      if (nou) all.push.apply(all, m)
    +      else m.forEach(function (m) {
    +        all[m] = true
    +      })
    +    }
    +  }
    +
    +  if (!nou) all = Object.keys(all)
    +
    +  if (!this.nosort) {
    +    all = all.sort(this.nocase ? alphasorti : alphasort)
    +  }
    +
    +  if (this.mark) {
    +    // at *some* point we statted all of these
    +    all = all.map(this._mark, this)
    +  }
    +
    +  this.log("emitting end", all)
    +
    +  this.EOF = this.found = all
    +  this.emitMatch(this.EOF)
    +}
    +
    +function alphasorti (a, b) {
    +  a = a.toLowerCase()
    +  b = b.toLowerCase()
    +  return alphasort(a, b)
    +}
    +
    +function alphasort (a, b) {
    +  return a > b ? 1 : a < b ? -1 : 0
    +}
    +
    +Glob.prototype._mark = function (p) {
    +  var c = this.cache[p]
    +  var m = p
    +  if (c) {
    +    var isDir = c === 2 || Array.isArray(c)
    +    var slash = p.slice(-1) === '/'
    +
    +    if (isDir && !slash)
    +      m += '/'
    +    else if (!isDir && slash)
    +      m = m.slice(0, -1)
    +
    +    if (m !== p) {
    +      this.statCache[m] = this.statCache[p]
    +      this.cache[m] = this.cache[p]
    +    }
    +  }
    +
    +  return m
    +}
    +
    +Glob.prototype.abort = function () {
    +  this.aborted = true
    +  this.emit("abort")
    +}
    +
    +Glob.prototype.pause = function () {
    +  if (this.paused) return
    +  if (this.sync)
    +    this.emit("error", new Error("Can't pause/resume sync glob"))
    +  this.paused = true
    +  this.emit("pause")
    +}
    +
    +Glob.prototype.resume = function () {
    +  if (!this.paused) return
    +  if (this.sync)
    +    this.emit("error", new Error("Can't pause/resume sync glob"))
    +  this.paused = false
    +  this.emit("resume")
    +  this._processEmitQueue()
    +  //process.nextTick(this.emit.bind(this, "resume"))
    +}
    +
    +Glob.prototype.emitMatch = function (m) {
    +  this.log('emitMatch', m)
    +  this._emitQueue.push(m)
    +  this._processEmitQueue()
    +}
    +
    +Glob.prototype._processEmitQueue = function (m) {
    +  this.log("pEQ paused=%j processing=%j m=%j", this.paused,
    +           this._processingEmitQueue, m)
    +  var done = false
    +  while (!this._processingEmitQueue &&
    +         !this.paused) {
    +    this._processingEmitQueue = true
    +    var m = this._emitQueue.shift()
    +    this.log(">processEmitQueue", m === this.EOF ? ":EOF:" : m)
    +    if (!m) {
    +      this.log(">processEmitQueue, falsey m")
    +      this._processingEmitQueue = false
    +      break
    +    }
    +
    +    if (m === this.EOF || !(this.mark && !this.stat)) {
    +      this.log("peq: unmarked, or eof")
    +      next.call(this, 0, false)
    +    } else if (this.statCache[m]) {
    +      var sc = this.statCache[m]
    +      var exists
    +      if (sc)
    +        exists = sc.isDirectory() ? 2 : 1
    +      this.log("peq: stat cached")
    +      next.call(this, exists, exists === 2)
    +    } else {
    +      this.log("peq: _stat, then next")
    +      this._stat(m, next)
    +    }
    +
    +    function next(exists, isDir) {
    +      this.log("next", m, exists, isDir)
    +      var ev = m === this.EOF ? "end" : "match"
    +
    +      // "end" can only happen once.
    +      assert(!this._endEmitted)
    +      if (ev === "end")
    +        this._endEmitted = true
    +
    +      if (exists) {
    +        // Doesn't mean it necessarily doesn't exist, it's possible
    +        // we just didn't check because we don't care that much, or
    +        // this is EOF anyway.
    +        if (isDir && !m.match(/\/$/)) {
    +          m = m + "/"
    +        } else if (!isDir && m.match(/\/$/)) {
    +          m = m.replace(/\/+$/, "")
    +        }
    +      }
    +      this.log("emit", ev, m)
    +      this.emit(ev, m)
    +      this._processingEmitQueue = false
    +      if (done && m !== this.EOF && !this.paused)
    +        this._processEmitQueue()
    +    }
    +  }
    +  done = true
    +}
    +
    +Glob.prototype._process = function (pattern, depth, index, cb_) {
    +  assert(this instanceof Glob)
    +
    +  var cb = function cb (er, res) {
    +    assert(this instanceof Glob)
    +    if (this.paused) {
    +      if (!this._processQueue) {
    +        this._processQueue = []
    +        this.once("resume", function () {
    +          var q = this._processQueue
    +          this._processQueue = null
    +          q.forEach(function (cb) { cb() })
    +        })
    +      }
    +      this._processQueue.push(cb_.bind(this, er, res))
    +    } else {
    +      cb_.call(this, er, res)
    +    }
    +  }.bind(this)
    +
    +  if (this.aborted) return cb()
    +
    +  if (depth > this.maxDepth) return cb()
    +
    +  // Get the first [n] parts of pattern that are all strings.
    +  var n = 0
    +  while (typeof pattern[n] === "string") {
    +    n ++
    +  }
    +  // now n is the index of the first one that is *not* a string.
    +
    +  // see if there's anything else
    +  var prefix
    +  switch (n) {
    +    // if not, then this is rather simple
    +    case pattern.length:
    +      prefix = pattern.join("/")
    +      this._stat(prefix, function (exists, isDir) {
    +        // either it's there, or it isn't.
    +        // nothing more to do, either way.
    +        if (exists) {
    +          if (prefix && isAbsolute(prefix) && !this.nomount) {
    +            if (prefix.charAt(0) === "/") {
    +              prefix = path.join(this.root, prefix)
    +            } else {
    +              prefix = path.resolve(this.root, prefix)
    +            }
    +          }
    +
    +          if (process.platform === "win32")
    +            prefix = prefix.replace(/\\/g, "/")
    +
    +          this.matches[index] = this.matches[index] || {}
    +          this.matches[index][prefix] = true
    +          this.emitMatch(prefix)
    +        }
    +        return cb()
    +      })
    +      return
    +
    +    case 0:
    +      // pattern *starts* with some non-trivial item.
    +      // going to readdir(cwd), but not include the prefix in matches.
    +      prefix = null
    +      break
    +
    +    default:
    +      // pattern has some string bits in the front.
    +      // whatever it starts with, whether that's "absolute" like /foo/bar,
    +      // or "relative" like "../baz"
    +      prefix = pattern.slice(0, n)
    +      prefix = prefix.join("/")
    +      break
    +  }
    +
    +  // get the list of entries.
    +  var read
    +  if (prefix === null) read = "."
    +  else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
    +    if (!prefix || !isAbsolute(prefix)) {
    +      prefix = path.join("/", prefix)
    +    }
    +    read = prefix = path.resolve(prefix)
    +
    +    // if (process.platform === "win32")
    +    //   read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
    +
    +    this.log('absolute: ', prefix, this.root, pattern, read)
    +  } else {
    +    read = prefix
    +  }
    +
    +  this.log('readdir(%j)', read, this.cwd, this.root)
    +
    +  return this._readdir(read, function (er, entries) {
    +    if (er) {
    +      // not a directory!
    +      // this means that, whatever else comes after this, it can never match
    +      return cb()
    +    }
    +
    +    // globstar is special
    +    if (pattern[n] === minimatch.GLOBSTAR) {
    +      // test without the globstar, and with every child both below
    +      // and replacing the globstar.
    +      var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
    +      entries.forEach(function (e) {
    +        if (e.charAt(0) === "." && !this.dot) return
    +        // instead of the globstar
    +        s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
    +        // below the globstar
    +        s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
    +      }, this)
    +
    +      s = s.filter(function (pattern) {
    +        var key = gsKey(pattern)
    +        var seen = !this._globstars[key]
    +        this._globstars[key] = true
    +        return seen
    +      }, this)
    +
    +      if (!s.length)
    +        return cb()
    +
    +      // now asyncForEach over this
    +      var l = s.length
    +      , errState = null
    +      s.forEach(function (gsPattern) {
    +        this._process(gsPattern, depth + 1, index, function (er) {
    +          if (errState) return
    +          if (er) return cb(errState = er)
    +          if (--l <= 0) return cb()
    +        })
    +      }, this)
    +
    +      return
    +    }
    +
    +    // not a globstar
    +    // It will only match dot entries if it starts with a dot, or if
    +    // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
    +    var pn = pattern[n]
    +    var rawGlob = pattern[n]._glob
    +    , dotOk = this.dot || rawGlob.charAt(0) === "."
    +
    +    entries = entries.filter(function (e) {
    +      return (e.charAt(0) !== "." || dotOk) &&
    +             e.match(pattern[n])
    +    })
    +
    +    // If n === pattern.length - 1, then there's no need for the extra stat
    +    // *unless* the user has specified "mark" or "stat" explicitly.
    +    // We know that they exist, since the readdir returned them.
    +    if (n === pattern.length - 1 &&
    +        !this.mark &&
    +        !this.stat) {
    +      entries.forEach(function (e) {
    +        if (prefix) {
    +          if (prefix !== "/") e = prefix + "/" + e
    +          else e = prefix + e
    +        }
    +        if (e.charAt(0) === "/" && !this.nomount) {
    +          e = path.join(this.root, e)
    +        }
    +
    +        if (process.platform === "win32")
    +          e = e.replace(/\\/g, "/")
    +
    +        this.matches[index] = this.matches[index] || {}
    +        this.matches[index][e] = true
    +        this.emitMatch(e)
    +      }, this)
    +      return cb.call(this)
    +    }
    +
    +
    +    // now test all the remaining entries as stand-ins for that part
    +    // of the pattern.
    +    var l = entries.length
    +    , errState = null
    +    if (l === 0) return cb() // no matches possible
    +    entries.forEach(function (e) {
    +      var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
    +      this._process(p, depth + 1, index, function (er) {
    +        if (errState) return
    +        if (er) return cb(errState = er)
    +        if (--l === 0) return cb.call(this)
    +      })
    +    }, this)
    +  })
    +
    +}
    +
    +function gsKey (pattern) {
    +  return '**' + pattern.map(function (p) {
    +    return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
    +  }).join('/')
    +}
    +
    +Glob.prototype._stat = function (f, cb) {
    +  assert(this instanceof Glob)
    +  var abs = f
    +  if (f.charAt(0) === "/") {
    +    abs = path.join(this.root, f)
    +  } else if (this.changedCwd) {
    +    abs = path.resolve(this.cwd, f)
    +  }
    +
    +  if (f.length > this.maxLength) {
    +    var er = new Error("Path name too long")
    +    er.code = "ENAMETOOLONG"
    +    er.path = f
    +    return this._afterStat(f, abs, cb, er)
    +  }
    +
    +  this.log('stat', [this.cwd, f, '=', abs])
    +
    +  if (!this.stat && this.cache.hasOwnProperty(f)) {
    +    var exists = this.cache[f]
    +    , isDir = exists && (Array.isArray(exists) || exists === 2)
    +    if (this.sync) return cb.call(this, !!exists, isDir)
    +    return process.nextTick(cb.bind(this, !!exists, isDir))
    +  }
    +
    +  var stat = this.statCache[abs]
    +  if (this.sync || stat) {
    +    var er
    +    try {
    +      stat = fs.statSync(abs)
    +    } catch (e) {
    +      er = e
    +    }
    +    this._afterStat(f, abs, cb, er, stat)
    +  } else {
    +    fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
    +  }
    +}
    +
    +Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
    +  var exists
    +  assert(this instanceof Glob)
    +
    +  if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
    +    this.log("should be ENOTDIR, fake it")
    +
    +    er = new Error("ENOTDIR, not a directory '" + abs + "'")
    +    er.path = abs
    +    er.code = "ENOTDIR"
    +    stat = null
    +  }
    +
    +  var emit = !this.statCache[abs]
    +  this.statCache[abs] = stat
    +
    +  if (er || !stat) {
    +    exists = false
    +  } else {
    +    exists = stat.isDirectory() ? 2 : 1
    +    if (emit)
    +      this.emit('stat', f, stat)
    +  }
    +  this.cache[f] = this.cache[f] || exists
    +  cb.call(this, !!exists, exists === 2)
    +}
    +
    +Glob.prototype._readdir = function (f, cb) {
    +  assert(this instanceof Glob)
    +  var abs = f
    +  if (f.charAt(0) === "/") {
    +    abs = path.join(this.root, f)
    +  } else if (isAbsolute(f)) {
    +    abs = f
    +  } else if (this.changedCwd) {
    +    abs = path.resolve(this.cwd, f)
    +  }
    +
    +  if (f.length > this.maxLength) {
    +    var er = new Error("Path name too long")
    +    er.code = "ENAMETOOLONG"
    +    er.path = f
    +    return this._afterReaddir(f, abs, cb, er)
    +  }
    +
    +  this.log('readdir', [this.cwd, f, abs])
    +  if (this.cache.hasOwnProperty(f)) {
    +    var c = this.cache[f]
    +    if (Array.isArray(c)) {
    +      if (this.sync) return cb.call(this, null, c)
    +      return process.nextTick(cb.bind(this, null, c))
    +    }
    +
    +    if (!c || c === 1) {
    +      // either ENOENT or ENOTDIR
    +      var code = c ? "ENOTDIR" : "ENOENT"
    +      , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
    +      er.path = f
    +      er.code = code
    +      this.log(f, er)
    +      if (this.sync) return cb.call(this, er)
    +      return process.nextTick(cb.bind(this, er))
    +    }
    +
    +    // at this point, c === 2, meaning it's a dir, but we haven't
    +    // had to read it yet, or c === true, meaning it's *something*
    +    // but we don't have any idea what.  Need to read it, either way.
    +  }
    +
    +  if (this.sync) {
    +    var er, entries
    +    try {
    +      entries = fs.readdirSync(abs)
    +    } catch (e) {
    +      er = e
    +    }
    +    return this._afterReaddir(f, abs, cb, er, entries)
    +  }
    +
    +  fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
    +}
    +
    +Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
    +  assert(this instanceof Glob)
    +  if (entries && !er) {
    +    this.cache[f] = entries
    +    // if we haven't asked to stat everything for suresies, then just
    +    // assume that everything in there exists, so we can avoid
    +    // having to stat it a second time.  This also gets us one step
    +    // further into ELOOP territory.
    +    if (!this.mark && !this.stat) {
    +      entries.forEach(function (e) {
    +        if (f === "/") e = f + e
    +        else e = f + "/" + e
    +        this.cache[e] = true
    +      }, this)
    +    }
    +
    +    return cb.call(this, er, entries)
    +  }
    +
    +  // now handle errors, and cache the information
    +  if (er) switch (er.code) {
    +    case "ENOTDIR": // totally normal. means it *does* exist.
    +      this.cache[f] = 1
    +      return cb.call(this, er)
    +    case "ENOENT": // not terribly unusual
    +    case "ELOOP":
    +    case "ENAMETOOLONG":
    +    case "UNKNOWN":
    +      this.cache[f] = false
    +      return cb.call(this, er)
    +    default: // some unusual error.  Treat as failure.
    +      this.cache[f] = false
    +      if (this.strict) this.emit("error", er)
    +      if (!this.silent) console.error("glob error", er)
    +      return cb.call(this, er)
    +  }
    +}
    +
    +var isAbsolute = process.platform === "win32" ? absWin : absUnix
    +
    +function absWin (p) {
    +  if (absUnix(p)) return true
    +  // pull off the device/UNC bit from a windows path.
    +  // from node's lib/path.js
    +  var splitDeviceRe =
    +      /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
    +    , result = splitDeviceRe.exec(p)
    +    , device = result[1] || ''
    +    , isUnc = device && device.charAt(1) !== ':'
    +    , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
    +
    +  return isAbsolute
    +}
    +
    +function absUnix (p) {
    +  return p.charAt(0) === "/" || p === ""
    +}
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/.npmignore b/node_modules/mocha/node_modules/glob/node_modules/minimatch/.npmignore
    new file mode 100644
    index 0000000..3c3629e
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/.npmignore
    @@ -0,0 +1 @@
    +node_modules
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/LICENSE b/node_modules/mocha/node_modules/glob/node_modules/minimatch/LICENSE
    new file mode 100644
    index 0000000..05a4010
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/LICENSE
    @@ -0,0 +1,23 @@
    +Copyright 2009, 2010, 2011 Isaac Z. Schlueter.
    +All rights reserved.
    +
    +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.
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/README.md b/node_modules/mocha/node_modules/glob/node_modules/minimatch/README.md
    new file mode 100644
    index 0000000..5b3967e
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/README.md
    @@ -0,0 +1,218 @@
    +# minimatch
    +
    +A minimal matching utility.
    +
    +[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.png)](http://travis-ci.org/isaacs/minimatch)
    +
    +
    +This is the matching library used internally by npm.
    +
    +Eventually, it will replace the C binding in node-glob.
    +
    +It works by converting glob expressions into JavaScript `RegExp`
    +objects.
    +
    +## Usage
    +
    +```javascript
    +var minimatch = require("minimatch")
    +
    +minimatch("bar.foo", "*.foo") // true!
    +minimatch("bar.foo", "*.bar") // false!
    +minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
    +```
    +
    +## Features
    +
    +Supports these glob features:
    +
    +* Brace Expansion
    +* Extended glob matching
    +* "Globstar" `**` matching
    +
    +See:
    +
    +* `man sh`
    +* `man bash`
    +* `man 3 fnmatch`
    +* `man 5 gitignore`
    +
    +## Minimatch Class
    +
    +Create a minimatch object by instanting the `minimatch.Minimatch` class.
    +
    +```javascript
    +var Minimatch = require("minimatch").Minimatch
    +var mm = new Minimatch(pattern, options)
    +```
    +
    +### Properties
    +
    +* `pattern` The original pattern the minimatch object represents.
    +* `options` The options supplied to the constructor.
    +* `set` A 2-dimensional array of regexp or string expressions.
    +  Each row in the
    +  array corresponds to a brace-expanded pattern.  Each item in the row
    +  corresponds to a single path-part.  For example, the pattern
    +  `{a,b/c}/d` would expand to a set of patterns like:
    +
    +        [ [ a, d ]
    +        , [ b, c, d ] ]
    +
    +    If a portion of the pattern doesn't have any "magic" in it
    +    (that is, it's something like `"foo"` rather than `fo*o?`), then it
    +    will be left as a string rather than converted to a regular
    +    expression.
    +
    +* `regexp` Created by the `makeRe` method.  A single regular expression
    +  expressing the entire pattern.  This is useful in cases where you wish
    +  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
    +* `negate` True if the pattern is negated.
    +* `comment` True if the pattern is a comment.
    +* `empty` True if the pattern is `""`.
    +
    +### Methods
    +
    +* `makeRe` Generate the `regexp` member if necessary, and return it.
    +  Will return `false` if the pattern is invalid.
    +* `match(fname)` Return true if the filename matches the pattern, or
    +  false otherwise.
    +* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
    +  filename, and match it against a single row in the `regExpSet`.  This
    +  method is mainly for internal use, but is exposed so that it can be
    +  used by a glob-walker that needs to avoid excessive filesystem calls.
    +
    +All other methods are internal, and will be called as necessary.
    +
    +## Functions
    +
    +The top-level exported function has a `cache` property, which is an LRU
    +cache set to store 100 items.  So, calling these methods repeatedly
    +with the same pattern and options will use the same Minimatch object,
    +saving the cost of parsing it multiple times.
    +
    +### minimatch(path, pattern, options)
    +
    +Main export.  Tests a path against the pattern using the options.
    +
    +```javascript
    +var isJS = minimatch(file, "*.js", { matchBase: true })
    +```
    +
    +### minimatch.filter(pattern, options)
    +
    +Returns a function that tests its
    +supplied argument, suitable for use with `Array.filter`.  Example:
    +
    +```javascript
    +var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
    +```
    +
    +### minimatch.match(list, pattern, options)
    +
    +Match against the list of
    +files, in the style of fnmatch or glob.  If nothing is matched, and
    +options.nonull is set, then return a list containing the pattern itself.
    +
    +```javascript
    +var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
    +```
    +
    +### minimatch.makeRe(pattern, options)
    +
    +Make a regular expression object from the pattern.
    +
    +## Options
    +
    +All options are `false` by default.
    +
    +### debug
    +
    +Dump a ton of stuff to stderr.
    +
    +### nobrace
    +
    +Do not expand `{a,b}` and `{1..3}` brace sets.
    +
    +### noglobstar
    +
    +Disable `**` matching against multiple folder names.
    +
    +### dot
    +
    +Allow patterns to match filenames starting with a period, even if
    +the pattern does not explicitly have a period in that spot.
    +
    +Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
    +is set.
    +
    +### noext
    +
    +Disable "extglob" style patterns like `+(a|b)`.
    +
    +### nocase
    +
    +Perform a case-insensitive match.
    +
    +### nonull
    +
    +When a match is not found by `minimatch.match`, return a list containing
    +the pattern itself if this option is set.  When not set, an empty list
    +is returned if there are no matches.
    +
    +### matchBase
    +
    +If set, then patterns without slashes will be matched
    +against the basename of the path if it contains slashes.  For example,
    +`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
    +
    +### nocomment
    +
    +Suppress the behavior of treating `#` at the start of a pattern as a
    +comment.
    +
    +### nonegate
    +
    +Suppress the behavior of treating a leading `!` character as negation.
    +
    +### flipNegate
    +
    +Returns from negate expressions the same as if they were not negated.
    +(Ie, true on a hit, false on a miss.)
    +
    +
    +## Comparisons to other fnmatch/glob implementations
    +
    +While strict compliance with the existing standards is a worthwhile
    +goal, some discrepancies exist between minimatch and other
    +implementations, and are intentional.
    +
    +If the pattern starts with a `!` character, then it is negated.  Set the
    +`nonegate` flag to suppress this behavior, and treat leading `!`
    +characters normally.  This is perhaps relevant if you wish to start the
    +pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
    +characters at the start of a pattern will negate the pattern multiple
    +times.
    +
    +If a pattern starts with `#`, then it is treated as a comment, and
    +will not match anything.  Use `\#` to match a literal `#` at the
    +start of a line, or set the `nocomment` flag to suppress this behavior.
    +
    +The double-star character `**` is supported by default, unless the
    +`noglobstar` flag is set.  This is supported in the manner of bsdglob
    +and bash 4.1, where `**` only has special significance if it is the only
    +thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
    +`a/**b` will not.
    +
    +If an escaped pattern has no matches, and the `nonull` flag is set,
    +then minimatch.match returns the pattern as-provided, rather than
    +interpreting the character escapes.  For example,
    +`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
    +`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
    +that it does not resolve escaped pattern characters.
    +
    +If brace expansion is not disabled, then it is performed before any
    +other interpretation of the glob pattern.  Thus, a pattern like
    +`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
    +**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
    +checked for validity.  Since those two are valid, matching proceeds.
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/minimatch.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/minimatch.js
    new file mode 100644
    index 0000000..4539678
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/minimatch.js
    @@ -0,0 +1,1061 @@
    +;(function (require, exports, module, platform) {
    +
    +if (module) module.exports = minimatch
    +else exports.minimatch = minimatch
    +
    +if (!require) {
    +  require = function (id) {
    +    switch (id) {
    +      case "sigmund": return function sigmund (obj) {
    +        return JSON.stringify(obj)
    +      }
    +      case "path": return { basename: function (f) {
    +        f = f.split(/[\/\\]/)
    +        var e = f.pop()
    +        if (!e) e = f.pop()
    +        return e
    +      }}
    +      case "lru-cache": return function LRUCache () {
    +        // not quite an LRU, but still space-limited.
    +        var cache = {}
    +        var cnt = 0
    +        this.set = function (k, v) {
    +          cnt ++
    +          if (cnt >= 100) cache = {}
    +          cache[k] = v
    +        }
    +        this.get = function (k) { return cache[k] }
    +      }
    +    }
    +  }
    +}
    +
    +minimatch.Minimatch = Minimatch
    +
    +var LRU = require("lru-cache")
    +  , cache = minimatch.cache = new LRU({max: 100})
    +  , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
    +  , sigmund = require("sigmund")
    +
    +var path = require("path")
    +  // any single thing other than /
    +  // don't need to escape / when using new RegExp()
    +  , qmark = "[^/]"
    +
    +  // * => any number of characters
    +  , star = qmark + "*?"
    +
    +  // ** when dots are allowed.  Anything goes, except .. and .
    +  // not (^ or / followed by one or two dots followed by $ or /),
    +  // followed by anything, any number of times.
    +  , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
    +
    +  // not a ^ or / followed by a dot,
    +  // followed by anything, any number of times.
    +  , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
    +
    +  // characters that need to be escaped in RegExp.
    +  , reSpecials = charSet("().*{}+?[]^$\\!")
    +
    +// "abc" -> { a:true, b:true, c:true }
    +function charSet (s) {
    +  return s.split("").reduce(function (set, c) {
    +    set[c] = true
    +    return set
    +  }, {})
    +}
    +
    +// normalizes slashes.
    +var slashSplit = /\/+/
    +
    +minimatch.filter = filter
    +function filter (pattern, options) {
    +  options = options || {}
    +  return function (p, i, list) {
    +    return minimatch(p, pattern, options)
    +  }
    +}
    +
    +function ext (a, b) {
    +  a = a || {}
    +  b = b || {}
    +  var t = {}
    +  Object.keys(b).forEach(function (k) {
    +    t[k] = b[k]
    +  })
    +  Object.keys(a).forEach(function (k) {
    +    t[k] = a[k]
    +  })
    +  return t
    +}
    +
    +minimatch.defaults = function (def) {
    +  if (!def || !Object.keys(def).length) return minimatch
    +
    +  var orig = minimatch
    +
    +  var m = function minimatch (p, pattern, options) {
    +    return orig.minimatch(p, pattern, ext(def, options))
    +  }
    +
    +  m.Minimatch = function Minimatch (pattern, options) {
    +    return new orig.Minimatch(pattern, ext(def, options))
    +  }
    +
    +  return m
    +}
    +
    +Minimatch.defaults = function (def) {
    +  if (!def || !Object.keys(def).length) return Minimatch
    +  return minimatch.defaults(def).Minimatch
    +}
    +
    +
    +function minimatch (p, pattern, options) {
    +  if (typeof pattern !== "string") {
    +    throw new TypeError("glob pattern string required")
    +  }
    +
    +  if (!options) options = {}
    +
    +  // shortcut: comments match nothing.
    +  if (!options.nocomment && pattern.charAt(0) === "#") {
    +    return false
    +  }
    +
    +  // "" only matches ""
    +  if (pattern.trim() === "") return p === ""
    +
    +  return new Minimatch(pattern, options).match(p)
    +}
    +
    +function Minimatch (pattern, options) {
    +  if (!(this instanceof Minimatch)) {
    +    return new Minimatch(pattern, options, cache)
    +  }
    +
    +  if (typeof pattern !== "string") {
    +    throw new TypeError("glob pattern string required")
    +  }
    +
    +  if (!options) options = {}
    +  pattern = pattern.trim()
    +
    +  // windows: need to use /, not \
    +  // On other platforms, \ is a valid (albeit bad) filename char.
    +  if (platform === "win32") {
    +    pattern = pattern.split("\\").join("/")
    +  }
    +
    +  // lru storage.
    +  // these things aren't particularly big, but walking down the string
    +  // and turning it into a regexp can get pretty costly.
    +  var cacheKey = pattern + "\n" + sigmund(options)
    +  var cached = minimatch.cache.get(cacheKey)
    +  if (cached) return cached
    +  minimatch.cache.set(cacheKey, this)
    +
    +  this.options = options
    +  this.set = []
    +  this.pattern = pattern
    +  this.regexp = null
    +  this.negate = false
    +  this.comment = false
    +  this.empty = false
    +
    +  // make the set of regexps etc.
    +  this.make()
    +}
    +
    +Minimatch.prototype.debug = function() {}
    +
    +Minimatch.prototype.make = make
    +function make () {
    +  // don't do it more than once.
    +  if (this._made) return
    +
    +  var pattern = this.pattern
    +  var options = this.options
    +
    +  // empty patterns and comments match nothing.
    +  if (!options.nocomment && pattern.charAt(0) === "#") {
    +    this.comment = true
    +    return
    +  }
    +  if (!pattern) {
    +    this.empty = true
    +    return
    +  }
    +
    +  // step 1: figure out negation, etc.
    +  this.parseNegate()
    +
    +  // step 2: expand braces
    +  var set = this.globSet = this.braceExpand()
    +
    +  if (options.debug) this.debug = console.error
    +
    +  this.debug(this.pattern, set)
    +
    +  // step 3: now we have a set, so turn each one into a series of path-portion
    +  // matching patterns.
    +  // These will be regexps, except in the case of "**", which is
    +  // set to the GLOBSTAR object for globstar behavior,
    +  // and will not contain any / characters
    +  set = this.globParts = set.map(function (s) {
    +    return s.split(slashSplit)
    +  })
    +
    +  this.debug(this.pattern, set)
    +
    +  // glob --> regexps
    +  set = set.map(function (s, si, set) {
    +    return s.map(this.parse, this)
    +  }, this)
    +
    +  this.debug(this.pattern, set)
    +
    +  // filter out everything that didn't compile properly.
    +  set = set.filter(function (s) {
    +    return -1 === s.indexOf(false)
    +  })
    +
    +  this.debug(this.pattern, set)
    +
    +  this.set = set
    +}
    +
    +Minimatch.prototype.parseNegate = parseNegate
    +function parseNegate () {
    +  var pattern = this.pattern
    +    , negate = false
    +    , options = this.options
    +    , negateOffset = 0
    +
    +  if (options.nonegate) return
    +
    +  for ( var i = 0, l = pattern.length
    +      ; i < l && pattern.charAt(i) === "!"
    +      ; i ++) {
    +    negate = !negate
    +    negateOffset ++
    +  }
    +
    +  if (negateOffset) this.pattern = pattern.substr(negateOffset)
    +  this.negate = negate
    +}
    +
    +// Brace expansion:
    +// a{b,c}d -> abd acd
    +// a{b,}c -> abc ac
    +// a{0..3}d -> a0d a1d a2d a3d
    +// a{b,c{d,e}f}g -> abg acdfg acefg
    +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
    +//
    +// Invalid sets are not expanded.
    +// a{2..}b -> a{2..}b
    +// a{b}c -> a{b}c
    +minimatch.braceExpand = function (pattern, options) {
    +  return new Minimatch(pattern, options).braceExpand()
    +}
    +
    +Minimatch.prototype.braceExpand = braceExpand
    +function braceExpand (pattern, options) {
    +  options = options || this.options
    +  pattern = typeof pattern === "undefined"
    +    ? this.pattern : pattern
    +
    +  if (typeof pattern === "undefined") {
    +    throw new Error("undefined pattern")
    +  }
    +
    +  if (options.nobrace ||
    +      !pattern.match(/\{.*\}/)) {
    +    // shortcut. no need to expand.
    +    return [pattern]
    +  }
    +
    +  var escaping = false
    +
    +  // examples and comments refer to this crazy pattern:
    +  // a{b,c{d,e},{f,g}h}x{y,z}
    +  // expected:
    +  // abxy
    +  // abxz
    +  // acdxy
    +  // acdxz
    +  // acexy
    +  // acexz
    +  // afhxy
    +  // afhxz
    +  // aghxy
    +  // aghxz
    +
    +  // everything before the first \{ is just a prefix.
    +  // So, we pluck that off, and work with the rest,
    +  // and then prepend it to everything we find.
    +  if (pattern.charAt(0) !== "{") {
    +    this.debug(pattern)
    +    var prefix = null
    +    for (var i = 0, l = pattern.length; i < l; i ++) {
    +      var c = pattern.charAt(i)
    +      this.debug(i, c)
    +      if (c === "\\") {
    +        escaping = !escaping
    +      } else if (c === "{" && !escaping) {
    +        prefix = pattern.substr(0, i)
    +        break
    +      }
    +    }
    +
    +    // actually no sets, all { were escaped.
    +    if (prefix === null) {
    +      this.debug("no sets")
    +      return [pattern]
    +    }
    +
    +   var tail = braceExpand.call(this, pattern.substr(i), options)
    +    return tail.map(function (t) {
    +      return prefix + t
    +    })
    +  }
    +
    +  // now we have something like:
    +  // {b,c{d,e},{f,g}h}x{y,z}
    +  // walk through the set, expanding each part, until
    +  // the set ends.  then, we'll expand the suffix.
    +  // If the set only has a single member, then'll put the {} back
    +
    +  // first, handle numeric sets, since they're easier
    +  var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
    +  if (numset) {
    +    this.debug("numset", numset[1], numset[2])
    +    var suf = braceExpand.call(this, pattern.substr(numset[0].length), options)
    +      , start = +numset[1]
    +      , end = +numset[2]
    +      , inc = start > end ? -1 : 1
    +      , set = []
    +    for (var i = start; i != (end + inc); i += inc) {
    +      // append all the suffixes
    +      for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
    +        set.push(i + suf[ii])
    +      }
    +    }
    +    return set
    +  }
    +
    +  // ok, walk through the set
    +  // We hope, somewhat optimistically, that there
    +  // will be a } at the end.
    +  // If the closing brace isn't found, then the pattern is
    +  // interpreted as braceExpand("\\" + pattern) so that
    +  // the leading \{ will be interpreted literally.
    +  var i = 1 // skip the \{
    +    , depth = 1
    +    , set = []
    +    , member = ""
    +    , sawEnd = false
    +    , escaping = false
    +
    +  function addMember () {
    +    set.push(member)
    +    member = ""
    +  }
    +
    +  this.debug("Entering for")
    +  FOR: for (i = 1, l = pattern.length; i < l; i ++) {
    +    var c = pattern.charAt(i)
    +    this.debug("", i, c)
    +
    +    if (escaping) {
    +      escaping = false
    +      member += "\\" + c
    +    } else {
    +      switch (c) {
    +        case "\\":
    +          escaping = true
    +          continue
    +
    +        case "{":
    +          depth ++
    +          member += "{"
    +          continue
    +
    +        case "}":
    +          depth --
    +          // if this closes the actual set, then we're done
    +          if (depth === 0) {
    +            addMember()
    +            // pluck off the close-brace
    +            i ++
    +            break FOR
    +          } else {
    +            member += c
    +            continue
    +          }
    +
    +        case ",":
    +          if (depth === 1) {
    +            addMember()
    +          } else {
    +            member += c
    +          }
    +          continue
    +
    +        default:
    +          member += c
    +          continue
    +      } // switch
    +    } // else
    +  } // for
    +
    +  // now we've either finished the set, and the suffix is
    +  // pattern.substr(i), or we have *not* closed the set,
    +  // and need to escape the leading brace
    +  if (depth !== 0) {
    +    this.debug("didn't close", pattern)
    +    return braceExpand.call(this, "\\" + pattern, options)
    +  }
    +
    +  // x{y,z} -> ["xy", "xz"]
    +  this.debug("set", set)
    +  this.debug("suffix", pattern.substr(i))
    +  var suf = braceExpand.call(this, pattern.substr(i), options)
    +  // ["b", "c{d,e}","{f,g}h"] ->
    +  //   [["b"], ["cd", "ce"], ["fh", "gh"]]
    +  var addBraces = set.length === 1
    +  this.debug("set pre-expanded", set)
    +  set = set.map(function (p) {
    +    return braceExpand.call(this, p, options)
    +  }, this)
    +  this.debug("set expanded", set)
    +
    +
    +  // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
    +  //   ["b", "cd", "ce", "fh", "gh"]
    +  set = set.reduce(function (l, r) {
    +    return l.concat(r)
    +  })
    +
    +  if (addBraces) {
    +    set = set.map(function (s) {
    +      return "{" + s + "}"
    +    })
    +  }
    +
    +  // now attach the suffixes.
    +  var ret = []
    +  for (var i = 0, l = set.length; i < l; i ++) {
    +    for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
    +      ret.push(set[i] + suf[ii])
    +    }
    +  }
    +  return ret
    +}
    +
    +// parse a component of the expanded set.
    +// At this point, no pattern may contain "/" in it
    +// so we're going to return a 2d array, where each entry is the full
    +// pattern, split on '/', and then turned into a regular expression.
    +// A regexp is made at the end which joins each array with an
    +// escaped /, and another full one which joins each regexp with |.
    +//
    +// Following the lead of Bash 4.1, note that "**" only has special meaning
    +// when it is the *only* thing in a path portion.  Otherwise, any series
    +// of * is equivalent to a single *.  Globstar behavior is enabled by
    +// default, and can be disabled by setting options.noglobstar.
    +Minimatch.prototype.parse = parse
    +var SUBPARSE = {}
    +function parse (pattern, isSub) {
    +  var options = this.options
    +
    +  // shortcuts
    +  if (!options.noglobstar && pattern === "**") return GLOBSTAR
    +  if (pattern === "") return ""
    +
    +  var re = ""
    +    , hasMagic = !!options.nocase
    +    , escaping = false
    +    // ? => one single character
    +    , patternListStack = []
    +    , plType
    +    , stateChar
    +    , inClass = false
    +    , reClassStart = -1
    +    , classStart = -1
    +    // . and .. never match anything that doesn't start with .,
    +    // even when options.dot is set.
    +    , patternStart = pattern.charAt(0) === "." ? "" // anything
    +      // not (start or / followed by . or .. followed by / or end)
    +      : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
    +      : "(?!\\.)"
    +    , self = this
    +
    +  function clearStateChar () {
    +    if (stateChar) {
    +      // we had some state-tracking character
    +      // that wasn't consumed by this pass.
    +      switch (stateChar) {
    +        case "*":
    +          re += star
    +          hasMagic = true
    +          break
    +        case "?":
    +          re += qmark
    +          hasMagic = true
    +          break
    +        default:
    +          re += "\\"+stateChar
    +          break
    +      }
    +      self.debug('clearStateChar %j %j', stateChar, re)
    +      stateChar = false
    +    }
    +  }
    +
    +  for ( var i = 0, len = pattern.length, c
    +      ; (i < len) && (c = pattern.charAt(i))
    +      ; i ++ ) {
    +
    +    this.debug("%s\t%s %s %j", pattern, i, re, c)
    +
    +    // skip over any that are escaped.
    +    if (escaping && reSpecials[c]) {
    +      re += "\\" + c
    +      escaping = false
    +      continue
    +    }
    +
    +    SWITCH: switch (c) {
    +      case "/":
    +        // completely not allowed, even escaped.
    +        // Should already be path-split by now.
    +        return false
    +
    +      case "\\":
    +        clearStateChar()
    +        escaping = true
    +        continue
    +
    +      // the various stateChar values
    +      // for the "extglob" stuff.
    +      case "?":
    +      case "*":
    +      case "+":
    +      case "@":
    +      case "!":
    +        this.debug("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
    +
    +        // all of those are literals inside a class, except that
    +        // the glob [!a] means [^a] in regexp
    +        if (inClass) {
    +          this.debug('  in class')
    +          if (c === "!" && i === classStart + 1) c = "^"
    +          re += c
    +          continue
    +        }
    +
    +        // if we already have a stateChar, then it means
    +        // that there was something like ** or +? in there.
    +        // Handle the stateChar, then proceed with this one.
    +        self.debug('call clearStateChar %j', stateChar)
    +        clearStateChar()
    +        stateChar = c
    +        // if extglob is disabled, then +(asdf|foo) isn't a thing.
    +        // just clear the statechar *now*, rather than even diving into
    +        // the patternList stuff.
    +        if (options.noext) clearStateChar()
    +        continue
    +
    +      case "(":
    +        if (inClass) {
    +          re += "("
    +          continue
    +        }
    +
    +        if (!stateChar) {
    +          re += "\\("
    +          continue
    +        }
    +
    +        plType = stateChar
    +        patternListStack.push({ type: plType
    +                              , start: i - 1
    +                              , reStart: re.length })
    +        // negation is (?:(?!js)[^/]*)
    +        re += stateChar === "!" ? "(?:(?!" : "(?:"
    +        this.debug('plType %j %j', stateChar, re)
    +        stateChar = false
    +        continue
    +
    +      case ")":
    +        if (inClass || !patternListStack.length) {
    +          re += "\\)"
    +          continue
    +        }
    +
    +        clearStateChar()
    +        hasMagic = true
    +        re += ")"
    +        plType = patternListStack.pop().type
    +        // negation is (?:(?!js)[^/]*)
    +        // The others are (?:)
    +        switch (plType) {
    +          case "!":
    +            re += "[^/]*?)"
    +            break
    +          case "?":
    +          case "+":
    +          case "*": re += plType
    +          case "@": break // the default anyway
    +        }
    +        continue
    +
    +      case "|":
    +        if (inClass || !patternListStack.length || escaping) {
    +          re += "\\|"
    +          escaping = false
    +          continue
    +        }
    +
    +        clearStateChar()
    +        re += "|"
    +        continue
    +
    +      // these are mostly the same in regexp and glob
    +      case "[":
    +        // swallow any state-tracking char before the [
    +        clearStateChar()
    +
    +        if (inClass) {
    +          re += "\\" + c
    +          continue
    +        }
    +
    +        inClass = true
    +        classStart = i
    +        reClassStart = re.length
    +        re += c
    +        continue
    +
    +      case "]":
    +        //  a right bracket shall lose its special
    +        //  meaning and represent itself in
    +        //  a bracket expression if it occurs
    +        //  first in the list.  -- POSIX.2 2.8.3.2
    +        if (i === classStart + 1 || !inClass) {
    +          re += "\\" + c
    +          escaping = false
    +          continue
    +        }
    +
    +        // finish up the class.
    +        hasMagic = true
    +        inClass = false
    +        re += c
    +        continue
    +
    +      default:
    +        // swallow any state char that wasn't consumed
    +        clearStateChar()
    +
    +        if (escaping) {
    +          // no need
    +          escaping = false
    +        } else if (reSpecials[c]
    +                   && !(c === "^" && inClass)) {
    +          re += "\\"
    +        }
    +
    +        re += c
    +
    +    } // switch
    +  } // for
    +
    +
    +  // handle the case where we left a class open.
    +  // "[abc" is valid, equivalent to "\[abc"
    +  if (inClass) {
    +    // split where the last [ was, and escape it
    +    // this is a huge pita.  We now have to re-walk
    +    // the contents of the would-be class to re-translate
    +    // any characters that were passed through as-is
    +    var cs = pattern.substr(classStart + 1)
    +      , sp = this.parse(cs, SUBPARSE)
    +    re = re.substr(0, reClassStart) + "\\[" + sp[0]
    +    hasMagic = hasMagic || sp[1]
    +  }
    +
    +  // handle the case where we had a +( thing at the *end*
    +  // of the pattern.
    +  // each pattern list stack adds 3 chars, and we need to go through
    +  // and escape any | chars that were passed through as-is for the regexp.
    +  // Go through and escape them, taking care not to double-escape any
    +  // | chars that were already escaped.
    +  var pl
    +  while (pl = patternListStack.pop()) {
    +    var tail = re.slice(pl.reStart + 3)
    +    // maybe some even number of \, then maybe 1 \, followed by a |
    +    tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
    +      if (!$2) {
    +        // the | isn't already escaped, so escape it.
    +        $2 = "\\"
    +      }
    +
    +      // need to escape all those slashes *again*, without escaping the
    +      // one that we need for escaping the | character.  As it works out,
    +      // escaping an even number of slashes can be done by simply repeating
    +      // it exactly after itself.  That's why this trick works.
    +      //
    +      // I am sorry that you have to see this.
    +      return $1 + $1 + $2 + "|"
    +    })
    +
    +    this.debug("tail=%j\n   %s", tail, tail)
    +    var t = pl.type === "*" ? star
    +          : pl.type === "?" ? qmark
    +          : "\\" + pl.type
    +
    +    hasMagic = true
    +    re = re.slice(0, pl.reStart)
    +       + t + "\\("
    +       + tail
    +  }
    +
    +  // handle trailing things that only matter at the very end.
    +  clearStateChar()
    +  if (escaping) {
    +    // trailing \\
    +    re += "\\\\"
    +  }
    +
    +  // only need to apply the nodot start if the re starts with
    +  // something that could conceivably capture a dot
    +  var addPatternStart = false
    +  switch (re.charAt(0)) {
    +    case ".":
    +    case "[":
    +    case "(": addPatternStart = true
    +  }
    +
    +  // if the re is not "" at this point, then we need to make sure
    +  // it doesn't match against an empty path part.
    +  // Otherwise a/* will match a/, which it should not.
    +  if (re !== "" && hasMagic) re = "(?=.)" + re
    +
    +  if (addPatternStart) re = patternStart + re
    +
    +  // parsing just a piece of a larger pattern.
    +  if (isSub === SUBPARSE) {
    +    return [ re, hasMagic ]
    +  }
    +
    +  // skip the regexp for non-magical patterns
    +  // unescape anything in it, though, so that it'll be
    +  // an exact match against a file etc.
    +  if (!hasMagic) {
    +    return globUnescape(pattern)
    +  }
    +
    +  var flags = options.nocase ? "i" : ""
    +    , regExp = new RegExp("^" + re + "$", flags)
    +
    +  regExp._glob = pattern
    +  regExp._src = re
    +
    +  return regExp
    +}
    +
    +minimatch.makeRe = function (pattern, options) {
    +  return new Minimatch(pattern, options || {}).makeRe()
    +}
    +
    +Minimatch.prototype.makeRe = makeRe
    +function makeRe () {
    +  if (this.regexp || this.regexp === false) return this.regexp
    +
    +  // at this point, this.set is a 2d array of partial
    +  // pattern strings, or "**".
    +  //
    +  // It's better to use .match().  This function shouldn't
    +  // be used, really, but it's pretty convenient sometimes,
    +  // when you just want to work with a regex.
    +  var set = this.set
    +
    +  if (!set.length) return this.regexp = false
    +  var options = this.options
    +
    +  var twoStar = options.noglobstar ? star
    +      : options.dot ? twoStarDot
    +      : twoStarNoDot
    +    , flags = options.nocase ? "i" : ""
    +
    +  var re = set.map(function (pattern) {
    +    return pattern.map(function (p) {
    +      return (p === GLOBSTAR) ? twoStar
    +           : (typeof p === "string") ? regExpEscape(p)
    +           : p._src
    +    }).join("\\\/")
    +  }).join("|")
    +
    +  // must match entire pattern
    +  // ending in a * or ** will make it less strict.
    +  re = "^(?:" + re + ")$"
    +
    +  // can match anything, as long as it's not this.
    +  if (this.negate) re = "^(?!" + re + ").*$"
    +
    +  try {
    +    return this.regexp = new RegExp(re, flags)
    +  } catch (ex) {
    +    return this.regexp = false
    +  }
    +}
    +
    +minimatch.match = function (list, pattern, options) {
    +  options = options || {}
    +  var mm = new Minimatch(pattern, options)
    +  list = list.filter(function (f) {
    +    return mm.match(f)
    +  })
    +  if (mm.options.nonull && !list.length) {
    +    list.push(pattern)
    +  }
    +  return list
    +}
    +
    +Minimatch.prototype.match = match
    +function match (f, partial) {
    +  this.debug("match", f, this.pattern)
    +  // short-circuit in the case of busted things.
    +  // comments, etc.
    +  if (this.comment) return false
    +  if (this.empty) return f === ""
    +
    +  if (f === "/" && partial) return true
    +
    +  var options = this.options
    +
    +  // windows: need to use /, not \
    +  // On other platforms, \ is a valid (albeit bad) filename char.
    +  if (platform === "win32") {
    +    f = f.split("\\").join("/")
    +  }
    +
    +  // treat the test path as a set of pathparts.
    +  f = f.split(slashSplit)
    +  this.debug(this.pattern, "split", f)
    +
    +  // just ONE of the pattern sets in this.set needs to match
    +  // in order for it to be valid.  If negating, then just one
    +  // match means that we have failed.
    +  // Either way, return on the first hit.
    +
    +  var set = this.set
    +  this.debug(this.pattern, "set", set)
    +
    +  // Find the basename of the path by looking for the last non-empty segment
    +  var filename;
    +  for (var i = f.length - 1; i >= 0; i--) {
    +    filename = f[i]
    +    if (filename) break
    +  }
    +
    +  for (var i = 0, l = set.length; i < l; i ++) {
    +    var pattern = set[i], file = f
    +    if (options.matchBase && pattern.length === 1) {
    +      file = [filename]
    +    }
    +    var hit = this.matchOne(file, pattern, partial)
    +    if (hit) {
    +      if (options.flipNegate) return true
    +      return !this.negate
    +    }
    +  }
    +
    +  // didn't get any hits.  this is success if it's a negative
    +  // pattern, failure otherwise.
    +  if (options.flipNegate) return false
    +  return this.negate
    +}
    +
    +// set partial to true to test if, for example,
    +// "/a/b" matches the start of "/*/b/*/d"
    +// Partial means, if you run out of file before you run
    +// out of pattern, then that's fine, as long as all
    +// the parts match.
    +Minimatch.prototype.matchOne = function (file, pattern, partial) {
    +  var options = this.options
    +
    +  this.debug("matchOne",
    +              { "this": this
    +              , file: file
    +              , pattern: pattern })
    +
    +  this.debug("matchOne", file.length, pattern.length)
    +
    +  for ( var fi = 0
    +          , pi = 0
    +          , fl = file.length
    +          , pl = pattern.length
    +      ; (fi < fl) && (pi < pl)
    +      ; fi ++, pi ++ ) {
    +
    +    this.debug("matchOne loop")
    +    var p = pattern[pi]
    +      , f = file[fi]
    +
    +    this.debug(pattern, p, f)
    +
    +    // should be impossible.
    +    // some invalid regexp stuff in the set.
    +    if (p === false) return false
    +
    +    if (p === GLOBSTAR) {
    +      this.debug('GLOBSTAR', [pattern, p, f])
    +
    +      // "**"
    +      // a/**/b/**/c would match the following:
    +      // a/b/x/y/z/c
    +      // a/x/y/z/b/c
    +      // a/b/x/b/x/c
    +      // a/b/c
    +      // To do this, take the rest of the pattern after
    +      // the **, and see if it would match the file remainder.
    +      // If so, return success.
    +      // If not, the ** "swallows" a segment, and try again.
    +      // This is recursively awful.
    +      //
    +      // a/**/b/**/c matching a/b/x/y/z/c
    +      // - a matches a
    +      // - doublestar
    +      //   - matchOne(b/x/y/z/c, b/**/c)
    +      //     - b matches b
    +      //     - doublestar
    +      //       - matchOne(x/y/z/c, c) -> no
    +      //       - matchOne(y/z/c, c) -> no
    +      //       - matchOne(z/c, c) -> no
    +      //       - matchOne(c, c) yes, hit
    +      var fr = fi
    +        , pr = pi + 1
    +      if (pr === pl) {
    +        this.debug('** at the end')
    +        // a ** at the end will just swallow the rest.
    +        // We have found a match.
    +        // however, it will not swallow /.x, unless
    +        // options.dot is set.
    +        // . and .. are *never* matched by **, for explosively
    +        // exponential reasons.
    +        for ( ; fi < fl; fi ++) {
    +          if (file[fi] === "." || file[fi] === ".." ||
    +              (!options.dot && file[fi].charAt(0) === ".")) return false
    +        }
    +        return true
    +      }
    +
    +      // ok, let's see if we can swallow whatever we can.
    +      WHILE: while (fr < fl) {
    +        var swallowee = file[fr]
    +
    +        this.debug('\nglobstar while',
    +                    file, fr, pattern, pr, swallowee)
    +
    +        // XXX remove this slice.  Just pass the start index.
    +        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
    +          this.debug('globstar found match!', fr, fl, swallowee)
    +          // found a match.
    +          return true
    +        } else {
    +          // can't swallow "." or ".." ever.
    +          // can only swallow ".foo" when explicitly asked.
    +          if (swallowee === "." || swallowee === ".." ||
    +              (!options.dot && swallowee.charAt(0) === ".")) {
    +            this.debug("dot detected!", file, fr, pattern, pr)
    +            break WHILE
    +          }
    +
    +          // ** swallows a segment, and continue.
    +          this.debug('globstar swallow a segment, and continue')
    +          fr ++
    +        }
    +      }
    +      // no match was found.
    +      // However, in partial mode, we can't say this is necessarily over.
    +      // If there's more *pattern* left, then
    +      if (partial) {
    +        // ran out of file
    +        this.debug("\n>>> no match, partial?", file, fr, pattern, pr)
    +        if (fr === fl) return true
    +      }
    +      return false
    +    }
    +
    +    // something other than **
    +    // non-magic patterns just have to match exactly
    +    // patterns with magic have been turned into regexps.
    +    var hit
    +    if (typeof p === "string") {
    +      if (options.nocase) {
    +        hit = f.toLowerCase() === p.toLowerCase()
    +      } else {
    +        hit = f === p
    +      }
    +      this.debug("string match", p, f, hit)
    +    } else {
    +      hit = f.match(p)
    +      this.debug("pattern match", p, f, hit)
    +    }
    +
    +    if (!hit) return false
    +  }
    +
    +  // Note: ending in / means that we'll get a final ""
    +  // at the end of the pattern.  This can only match a
    +  // corresponding "" at the end of the file.
    +  // If the file ends in /, then it can only match a
    +  // a pattern that ends in /, unless the pattern just
    +  // doesn't have any more for it. But, a/b/ should *not*
    +  // match "a/b/*", even though "" matches against the
    +  // [^/]*? pattern, except in partial mode, where it might
    +  // simply not be reached yet.
    +  // However, a/b/ should still satisfy a/*
    +
    +  // now either we fell off the end of the pattern, or we're done.
    +  if (fi === fl && pi === pl) {
    +    // ran out of pattern and filename at the same time.
    +    // an exact hit!
    +    return true
    +  } else if (fi === fl) {
    +    // ran out of file, but still had pattern left.
    +    // this is ok if we're doing the match as part of
    +    // a glob fs traversal.
    +    return partial
    +  } else if (pi === pl) {
    +    // ran out of pattern, still have file left.
    +    // this is only acceptable if we're on the very last
    +    // empty segment of a file with a trailing slash.
    +    // a/* should match a/b/
    +    var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
    +    return emptyFileEnd
    +  }
    +
    +  // should be unreachable.
    +  throw new Error("wtf?")
    +}
    +
    +
    +// replace stuff like \* with *
    +function globUnescape (s) {
    +  return s.replace(/\\(.)/g, "$1")
    +}
    +
    +
    +function regExpEscape (s) {
    +  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
    +}
    +
    +})( typeof require === "function" ? require : null,
    +    this,
    +    typeof module === "object" ? module : null,
    +    typeof process === "object" ? process.platform : "win32"
    +  )
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
    new file mode 100644
    index 0000000..07e6e47
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.npmignore
    @@ -0,0 +1 @@
    +/node_modules
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.travis.yml b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.travis.yml
    new file mode 100644
    index 0000000..4af02b3
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/.travis.yml
    @@ -0,0 +1,8 @@
    +language: node_js
    +node_js:
    +  - '0.8'
    +  - '0.10'
    +  - '0.12'
    +  - 'iojs'
    +before_install:
    +  - npm install -g npm@latest
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
    new file mode 100644
    index 0000000..4a0bc50
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS
    @@ -0,0 +1,14 @@
    +# Authors, sorted by whether or not they are me
    +Isaac Z. Schlueter 
    +Brian Cottingham 
    +Carlos Brito Lage 
    +Jesse Dailey 
    +Kevin O'Hara 
    +Marco Rogers 
    +Mark Cavage 
    +Marko Mikulicic 
    +Nathan Rajlich 
    +Satheesh Natesan 
    +Trent Mick 
    +ashleybrener 
    +n4kz 
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
    new file mode 100644
    index 0000000..19129e3
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/LICENSE
    @@ -0,0 +1,15 @@
    +The ISC License
    +
    +Copyright (c) Isaac Z. Schlueter and Contributors
    +
    +Permission to use, copy, modify, and/or distribute this software for any
    +purpose with or without fee is hereby granted, provided that the above
    +copyright notice and this permission notice appear in all copies.
    +
    +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
    +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
    new file mode 100644
    index 0000000..c06814e
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/README.md
    @@ -0,0 +1,137 @@
    +# lru cache
    +
    +A cache object that deletes the least-recently-used items.
    +
    +## Usage:
    +
    +```javascript
    +var LRU = require("lru-cache")
    +  , options = { max: 500
    +              , length: function (n) { return n * 2 }
    +              , dispose: function (key, n) { n.close() }
    +              , maxAge: 1000 * 60 * 60 }
    +  , cache = LRU(options)
    +  , otherCache = LRU(50) // sets just the max size
    +
    +cache.set("key", "value")
    +cache.get("key") // "value"
    +
    +cache.reset()    // empty the cache
    +```
    +
    +If you put more stuff in it, then items will fall out.
    +
    +If you try to put an oversized thing in it, then it'll fall out right
    +away.
    +
    +## Keys should always be Strings or Numbers
    +
    +Note: this module will print warnings to `console.error` if you use a
    +key that is not a String or Number.  Because items are stored in an
    +object, which coerces keys to a string, it won't go well for you if
    +you try to use a key that is not a unique string, it'll cause surprise
    +collisions.  For example:
    +
    +```JavaScript
    +// Bad Example!  Dont' do this!
    +var cache = LRU()
    +var a = {}
    +var b = {}
    +cache.set(a, 'this is a')
    +cache.set(b, 'this is b')
    +console.log(cache.get(a)) // prints: 'this is b'
    +```
    +
    +## Options
    +
    +* `max` The maximum size of the cache, checked by applying the length
    +  function to all values in the cache.  Not setting this is kind of
    +  silly, since that's the whole purpose of this lib, but it defaults
    +  to `Infinity`.
    +* `maxAge` Maximum age in ms.  Items are not pro-actively pruned out
    +  as they age, but if you try to get an item that is too old, it'll
    +  drop it and return undefined instead of giving it to you.
    +* `length` Function that is used to calculate the length of stored
    +  items.  If you're storing strings or buffers, then you probably want
    +  to do something like `function(n){return n.length}`.  The default is
    +  `function(n){return 1}`, which is fine if you want to store `max`
    +  like-sized things.
    +* `dispose` Function that is called on items when they are dropped
    +  from the cache.  This can be handy if you want to close file
    +  descriptors or do other cleanup tasks when items are no longer
    +  accessible.  Called with `key, value`.  It's called *before*
    +  actually removing the item from the internal cache, so if you want
    +  to immediately put it back in, you'll have to do that in a
    +  `nextTick` or `setTimeout` callback or it won't do anything.
    +* `stale` By default, if you set a `maxAge`, it'll only actually pull
    +  stale items out of the cache when you `get(key)`.  (That is, it's
    +  not pre-emptively doing a `setTimeout` or anything.)  If you set
    +  `stale:true`, it'll return the stale value before deleting it.  If
    +  you don't set this, then it'll return `undefined` when you try to
    +  get a stale entry, as if it had already been deleted.
    +
    +## API
    +
    +* `set(key, value, maxAge)`
    +* `get(key) => value`
    +
    +    Both of these will update the "recently used"-ness of the key.
    +    They do what you think. `max` is optional and overrides the
    +    cache `max` option if provided.
    +
    +* `peek(key)`
    +
    +    Returns the key value (or `undefined` if not found) without
    +    updating the "recently used"-ness of the key.
    +
    +    (If you find yourself using this a lot, you *might* be using the
    +    wrong sort of data structure, but there are some use cases where
    +    it's handy.)
    +
    +* `del(key)`
    +
    +    Deletes a key out of the cache.
    +
    +* `reset()`
    +
    +    Clear the cache entirely, throwing away all values.
    +
    +* `has(key)`
    +
    +    Check if a key is in the cache, without updating the recent-ness
    +    or deleting it for being stale.
    +
    +* `forEach(function(value,key,cache), [thisp])`
    +
    +    Just like `Array.prototype.forEach`.  Iterates over all the keys
    +    in the cache, in order of recent-ness.  (Ie, more recently used
    +    items are iterated over first.)
    +
    +* `keys()`
    +
    +    Return an array of the keys in the cache.
    +
    +* `values()`
    +
    +    Return an array of the values in the cache.
    +
    +* `length()`
    +
    +    Return total length of objects in cache taking into account
    +    `length` options function.
    +
    +* `itemCount`
    +
    +    Return total quantity of objects currently in cache. Note, that
    +    `stale` (see options) items are returned as part of this item
    +    count.
    +
    +* `dump()`
    +
    +    Return an array of the cache entries ready for serialization and usage
    +    with 'destinationCache.load(arr)`.
    +
    +* `load(cacheEntriesArray)`
    +
    +    Loads another cache entries array, obtained with `sourceCache.dump()`,
    +    into the cache. The destination cache is reset before loading new entries
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
    new file mode 100644
    index 0000000..2bbe653
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js
    @@ -0,0 +1,334 @@
    +;(function () { // closure for web browsers
    +
    +if (typeof module === 'object' && module.exports) {
    +  module.exports = LRUCache
    +} else {
    +  // just set the global for non-node platforms.
    +  this.LRUCache = LRUCache
    +}
    +
    +function hOP (obj, key) {
    +  return Object.prototype.hasOwnProperty.call(obj, key)
    +}
    +
    +function naiveLength () { return 1 }
    +
    +var didTypeWarning = false
    +function typeCheckKey(key) {
    +  if (!didTypeWarning && typeof key !== 'string' && typeof key !== 'number') {
    +    didTypeWarning = true
    +    console.error(new TypeError("LRU: key must be a string or number. Almost certainly a bug! " + typeof key).stack)
    +  }
    +}
    +
    +function LRUCache (options) {
    +  if (!(this instanceof LRUCache))
    +    return new LRUCache(options)
    +
    +  if (typeof options === 'number')
    +    options = { max: options }
    +
    +  if (!options)
    +    options = {}
    +
    +  this._max = options.max
    +  // Kind of weird to have a default max of Infinity, but oh well.
    +  if (!this._max || !(typeof this._max === "number") || this._max <= 0 )
    +    this._max = Infinity
    +
    +  this._lengthCalculator = options.length || naiveLength
    +  if (typeof this._lengthCalculator !== "function")
    +    this._lengthCalculator = naiveLength
    +
    +  this._allowStale = options.stale || false
    +  this._maxAge = options.maxAge || null
    +  this._dispose = options.dispose
    +  this.reset()
    +}
    +
    +// resize the cache when the max changes.
    +Object.defineProperty(LRUCache.prototype, "max",
    +  { set : function (mL) {
    +      if (!mL || !(typeof mL === "number") || mL <= 0 ) mL = Infinity
    +      this._max = mL
    +      if (this._length > this._max) trim(this)
    +    }
    +  , get : function () { return this._max }
    +  , enumerable : true
    +  })
    +
    +// resize the cache when the lengthCalculator changes.
    +Object.defineProperty(LRUCache.prototype, "lengthCalculator",
    +  { set : function (lC) {
    +      if (typeof lC !== "function") {
    +        this._lengthCalculator = naiveLength
    +        this._length = this._itemCount
    +        for (var key in this._cache) {
    +          this._cache[key].length = 1
    +        }
    +      } else {
    +        this._lengthCalculator = lC
    +        this._length = 0
    +        for (var key in this._cache) {
    +          this._cache[key].length = this._lengthCalculator(this._cache[key].value)
    +          this._length += this._cache[key].length
    +        }
    +      }
    +
    +      if (this._length > this._max) trim(this)
    +    }
    +  , get : function () { return this._lengthCalculator }
    +  , enumerable : true
    +  })
    +
    +Object.defineProperty(LRUCache.prototype, "length",
    +  { get : function () { return this._length }
    +  , enumerable : true
    +  })
    +
    +
    +Object.defineProperty(LRUCache.prototype, "itemCount",
    +  { get : function () { return this._itemCount }
    +  , enumerable : true
    +  })
    +
    +LRUCache.prototype.forEach = function (fn, thisp) {
    +  thisp = thisp || this
    +  var i = 0
    +  var itemCount = this._itemCount
    +
    +  for (var k = this._mru - 1; k >= 0 && i < itemCount; k--) if (this._lruList[k]) {
    +    i++
    +    var hit = this._lruList[k]
    +    if (isStale(this, hit)) {
    +      del(this, hit)
    +      if (!this._allowStale) hit = undefined
    +    }
    +    if (hit) {
    +      fn.call(thisp, hit.value, hit.key, this)
    +    }
    +  }
    +}
    +
    +LRUCache.prototype.keys = function () {
    +  var keys = new Array(this._itemCount)
    +  var i = 0
    +  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
    +    var hit = this._lruList[k]
    +    keys[i++] = hit.key
    +  }
    +  return keys
    +}
    +
    +LRUCache.prototype.values = function () {
    +  var values = new Array(this._itemCount)
    +  var i = 0
    +  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
    +    var hit = this._lruList[k]
    +    values[i++] = hit.value
    +  }
    +  return values
    +}
    +
    +LRUCache.prototype.reset = function () {
    +  if (this._dispose && this._cache) {
    +    for (var k in this._cache) {
    +      this._dispose(k, this._cache[k].value)
    +    }
    +  }
    +
    +  this._cache = Object.create(null) // hash of items by key
    +  this._lruList = Object.create(null) // list of items in order of use recency
    +  this._mru = 0 // most recently used
    +  this._lru = 0 // least recently used
    +  this._length = 0 // number of items in the list
    +  this._itemCount = 0
    +}
    +
    +LRUCache.prototype.dump = function () {
    +  var arr = []
    +  var i = 0
    +
    +  for (var k = this._mru - 1; k >= 0 && i < this._itemCount; k--) if (this._lruList[k]) {
    +    var hit = this._lruList[k]
    +    if (!isStale(this, hit)) {
    +      //Do not store staled hits
    +      ++i
    +      arr.push({
    +        k: hit.key,
    +        v: hit.value,
    +        e: hit.now + (hit.maxAge || 0)
    +      });
    +    }
    +  }
    +  //arr has the most read first
    +  return arr
    +}
    +
    +LRUCache.prototype.dumpLru = function () {
    +  return this._lruList
    +}
    +
    +LRUCache.prototype.set = function (key, value, maxAge) {
    +  maxAge = maxAge || this._maxAge
    +  typeCheckKey(key)
    +
    +  var now = maxAge ? Date.now() : 0
    +  var len = this._lengthCalculator(value)
    +
    +  if (hOP(this._cache, key)) {
    +    if (len > this._max) {
    +      del(this, this._cache[key])
    +      return false
    +    }
    +    // dispose of the old one before overwriting
    +    if (this._dispose)
    +      this._dispose(key, this._cache[key].value)
    +
    +    this._cache[key].now = now
    +    this._cache[key].maxAge = maxAge
    +    this._cache[key].value = value
    +    this._length += (len - this._cache[key].length)
    +    this._cache[key].length = len
    +    this.get(key)
    +
    +    if (this._length > this._max)
    +      trim(this)
    +
    +    return true
    +  }
    +
    +  var hit = new Entry(key, value, this._mru++, len, now, maxAge)
    +
    +  // oversized objects fall out of cache automatically.
    +  if (hit.length > this._max) {
    +    if (this._dispose) this._dispose(key, value)
    +    return false
    +  }
    +
    +  this._length += hit.length
    +  this._lruList[hit.lu] = this._cache[key] = hit
    +  this._itemCount ++
    +
    +  if (this._length > this._max)
    +    trim(this)
    +
    +  return true
    +}
    +
    +LRUCache.prototype.has = function (key) {
    +  typeCheckKey(key)
    +  if (!hOP(this._cache, key)) return false
    +  var hit = this._cache[key]
    +  if (isStale(this, hit)) {
    +    return false
    +  }
    +  return true
    +}
    +
    +LRUCache.prototype.get = function (key) {
    +  typeCheckKey(key)
    +  return get(this, key, true)
    +}
    +
    +LRUCache.prototype.peek = function (key) {
    +  typeCheckKey(key)
    +  return get(this, key, false)
    +}
    +
    +LRUCache.prototype.pop = function () {
    +  var hit = this._lruList[this._lru]
    +  del(this, hit)
    +  return hit || null
    +}
    +
    +LRUCache.prototype.del = function (key) {
    +  typeCheckKey(key)
    +  del(this, this._cache[key])
    +}
    +
    +LRUCache.prototype.load = function (arr) {
    +  //reset the cache
    +  this.reset();
    +
    +  var now = Date.now()
    +  //A previous serialized cache has the most recent items first
    +  for (var l = arr.length - 1; l >= 0; l-- ) {
    +    var hit = arr[l]
    +    typeCheckKey(hit.k)
    +    var expiresAt = hit.e || 0
    +    if (expiresAt === 0) {
    +      //the item was created without expiration in a non aged cache
    +      this.set(hit.k, hit.v)
    +    } else {
    +      var maxAge = expiresAt - now
    +      //dont add already expired items
    +      if (maxAge > 0) this.set(hit.k, hit.v, maxAge)
    +    }
    +  }
    +}
    +
    +function get (self, key, doUse) {
    +  typeCheckKey(key)
    +  var hit = self._cache[key]
    +  if (hit) {
    +    if (isStale(self, hit)) {
    +      del(self, hit)
    +      if (!self._allowStale) hit = undefined
    +    } else {
    +      if (doUse) use(self, hit)
    +    }
    +    if (hit) hit = hit.value
    +  }
    +  return hit
    +}
    +
    +function isStale(self, hit) {
    +  if (!hit || (!hit.maxAge && !self._maxAge)) return false
    +  var stale = false;
    +  var diff = Date.now() - hit.now
    +  if (hit.maxAge) {
    +    stale = diff > hit.maxAge
    +  } else {
    +    stale = self._maxAge && (diff > self._maxAge)
    +  }
    +  return stale;
    +}
    +
    +function use (self, hit) {
    +  shiftLU(self, hit)
    +  hit.lu = self._mru ++
    +  self._lruList[hit.lu] = hit
    +}
    +
    +function trim (self) {
    +  while (self._lru < self._mru && self._length > self._max)
    +    del(self, self._lruList[self._lru])
    +}
    +
    +function shiftLU (self, hit) {
    +  delete self._lruList[ hit.lu ]
    +  while (self._lru < self._mru && !self._lruList[self._lru]) self._lru ++
    +}
    +
    +function del (self, hit) {
    +  if (hit) {
    +    if (self._dispose) self._dispose(hit.key, hit.value)
    +    self._length -= hit.length
    +    self._itemCount --
    +    delete self._cache[ hit.key ]
    +    shiftLU(self, hit)
    +  }
    +}
    +
    +// classy, since V8 prefers predictable objects.
    +function Entry (key, value, lu, length, now, maxAge) {
    +  this.key = key
    +  this.value = value
    +  this.lu = lu
    +  this.length = length
    +  this.now = now
    +  if (maxAge) this.maxAge = maxAge
    +}
    +
    +})()
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
    new file mode 100644
    index 0000000..280389b
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/package.json
    @@ -0,0 +1,58 @@
    +{
    +  "name": "lru-cache",
    +  "description": "A cache object that deletes the least-recently-used items.",
    +  "version": "2.7.3",
    +  "author": {
    +    "name": "Isaac Z. Schlueter",
    +    "email": "i@izs.me"
    +  },
    +  "keywords": [
    +    "mru",
    +    "lru",
    +    "cache"
    +  ],
    +  "scripts": {
    +    "test": "tap test --gc"
    +  },
    +  "main": "lib/lru-cache.js",
    +  "repository": {
    +    "type": "git",
    +    "url": "git://github.com/isaacs/node-lru-cache.git"
    +  },
    +  "devDependencies": {
    +    "tap": "^1.2.0",
    +    "weak": ""
    +  },
    +  "license": "ISC",
    +  "gitHead": "292048199f6d28b77fbe584279a1898e25e4c714",
    +  "bugs": {
    +    "url": "https://github.com/isaacs/node-lru-cache/issues"
    +  },
    +  "homepage": "https://github.com/isaacs/node-lru-cache#readme",
    +  "_id": "lru-cache@2.7.3",
    +  "_shasum": "6d4524e8b955f95d4f5b58851ce21dd72fb4e952",
    +  "_from": "lru-cache@>=2.0.0 <3.0.0",
    +  "_npmVersion": "3.3.2",
    +  "_nodeVersion": "4.0.0",
    +  "_npmUser": {
    +    "name": "isaacs",
    +    "email": "i@izs.me"
    +  },
    +  "dist": {
    +    "shasum": "6d4524e8b955f95d4f5b58851ce21dd72fb4e952",
    +    "tarball": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz"
    +  },
    +  "maintainers": [
    +    {
    +      "name": "isaacs",
    +      "email": "isaacs@npmjs.com"
    +    },
    +    {
    +      "name": "othiym23",
    +      "email": "ogd@aoaioxxysz.net"
    +    }
    +  ],
    +  "directories": {},
    +  "_resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
    new file mode 100644
    index 0000000..b47225f
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/basic.js
    @@ -0,0 +1,396 @@
    +var test = require("tap").test
    +  , LRU = require("../")
    +
    +test("basic", function (t) {
    +  var cache = new LRU({max: 10})
    +  cache.set("key", "value")
    +  t.equal(cache.get("key"), "value")
    +  t.equal(cache.get("nada"), undefined)
    +  t.equal(cache.length, 1)
    +  t.equal(cache.max, 10)
    +  t.end()
    +})
    +
    +test("least recently set", function (t) {
    +  var cache = new LRU(2)
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +  cache.set("c", "C")
    +  t.equal(cache.get("c"), "C")
    +  t.equal(cache.get("b"), "B")
    +  t.equal(cache.get("a"), undefined)
    +  t.end()
    +})
    +
    +test("lru recently gotten", function (t) {
    +  var cache = new LRU(2)
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +  cache.get("a")
    +  cache.set("c", "C")
    +  t.equal(cache.get("c"), "C")
    +  t.equal(cache.get("b"), undefined)
    +  t.equal(cache.get("a"), "A")
    +  t.end()
    +})
    +
    +test("del", function (t) {
    +  var cache = new LRU(2)
    +  cache.set("a", "A")
    +  cache.del("a")
    +  t.equal(cache.get("a"), undefined)
    +  t.end()
    +})
    +
    +test("max", function (t) {
    +  var cache = new LRU(3)
    +
    +  // test changing the max, verify that the LRU items get dropped.
    +  cache.max = 100
    +  for (var i = 0; i < 100; i ++) cache.set(i, i)
    +  t.equal(cache.length, 100)
    +  for (var i = 0; i < 100; i ++) {
    +    t.equal(cache.get(i), i)
    +  }
    +  cache.max = 3
    +  t.equal(cache.length, 3)
    +  for (var i = 0; i < 97; i ++) {
    +    t.equal(cache.get(i), undefined)
    +  }
    +  for (var i = 98; i < 100; i ++) {
    +    t.equal(cache.get(i), i)
    +  }
    +
    +  // now remove the max restriction, and try again.
    +  cache.max = "hello"
    +  for (var i = 0; i < 100; i ++) cache.set(i, i)
    +  t.equal(cache.length, 100)
    +  for (var i = 0; i < 100; i ++) {
    +    t.equal(cache.get(i), i)
    +  }
    +  // should trigger an immediate resize
    +  cache.max = 3
    +  t.equal(cache.length, 3)
    +  for (var i = 0; i < 97; i ++) {
    +    t.equal(cache.get(i), undefined)
    +  }
    +  for (var i = 98; i < 100; i ++) {
    +    t.equal(cache.get(i), i)
    +  }
    +  t.end()
    +})
    +
    +test("reset", function (t) {
    +  var cache = new LRU(10)
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +  cache.reset()
    +  t.equal(cache.length, 0)
    +  t.equal(cache.max, 10)
    +  t.equal(cache.get("a"), undefined)
    +  t.equal(cache.get("b"), undefined)
    +  t.end()
    +})
    +
    +
    +test("basic with weighed length", function (t) {
    +  var cache = new LRU({
    +    max: 100,
    +    length: function (item) { return item.size }
    +  })
    +  cache.set("key", {val: "value", size: 50})
    +  t.equal(cache.get("key").val, "value")
    +  t.equal(cache.get("nada"), undefined)
    +  t.equal(cache.lengthCalculator(cache.get("key")), 50)
    +  t.equal(cache.length, 50)
    +  t.equal(cache.max, 100)
    +  t.end()
    +})
    +
    +
    +test("weighed length item too large", function (t) {
    +  var cache = new LRU({
    +    max: 10,
    +    length: function (item) { return item.size }
    +  })
    +  t.equal(cache.max, 10)
    +
    +  // should fall out immediately
    +  cache.set("key", {val: "value", size: 50})
    +
    +  t.equal(cache.length, 0)
    +  t.equal(cache.get("key"), undefined)
    +  t.end()
    +})
    +
    +test("least recently set with weighed length", function (t) {
    +  var cache = new LRU({
    +    max:8,
    +    length: function (item) { return item.length }
    +  })
    +  cache.set("a", "A")
    +  cache.set("b", "BB")
    +  cache.set("c", "CCC")
    +  cache.set("d", "DDDD")
    +  t.equal(cache.get("d"), "DDDD")
    +  t.equal(cache.get("c"), "CCC")
    +  t.equal(cache.get("b"), undefined)
    +  t.equal(cache.get("a"), undefined)
    +  t.end()
    +})
    +
    +test("lru recently gotten with weighed length", function (t) {
    +  var cache = new LRU({
    +    max: 8,
    +    length: function (item) { return item.length }
    +  })
    +  cache.set("a", "A")
    +  cache.set("b", "BB")
    +  cache.set("c", "CCC")
    +  cache.get("a")
    +  cache.get("b")
    +  cache.set("d", "DDDD")
    +  t.equal(cache.get("c"), undefined)
    +  t.equal(cache.get("d"), "DDDD")
    +  t.equal(cache.get("b"), "BB")
    +  t.equal(cache.get("a"), "A")
    +  t.end()
    +})
    +
    +test("lru recently updated with weighed length", function (t) {
    +  var cache = new LRU({
    +    max: 8,
    +    length: function (item) { return item.length }
    +  })
    +  cache.set("a", "A")
    +  cache.set("b", "BB")
    +  cache.set("c", "CCC")
    +  t.equal(cache.length, 6) //CCC BB A
    +  cache.set("a", "+A")
    +  t.equal(cache.length, 7) //+A CCC BB
    +  cache.set("b", "++BB")
    +  t.equal(cache.length, 6) //++BB +A
    +  t.equal(cache.get("c"), undefined)
    +
    +  cache.set("c", "oversized")
    +  t.equal(cache.length, 6) //++BB +A
    +  t.equal(cache.get("c"), undefined)
    +
    +  cache.set("a", "oversized")
    +  t.equal(cache.length, 4) //++BB
    +  t.equal(cache.get("a"), undefined)
    +  t.equal(cache.get("b"), "++BB")
    +  t.end()
    +})
    +
    +test("set returns proper booleans", function(t) {
    +  var cache = new LRU({
    +    max: 5,
    +    length: function (item) { return item.length }
    +  })
    +
    +  t.equal(cache.set("a", "A"), true)
    +
    +  // should return false for max exceeded
    +  t.equal(cache.set("b", "donuts"), false)
    +
    +  t.equal(cache.set("b", "B"), true)
    +  t.equal(cache.set("c", "CCCC"), true)
    +  t.end()
    +})
    +
    +test("drop the old items", function(t) {
    +  var cache = new LRU({
    +    max: 5,
    +    maxAge: 50
    +  })
    +
    +  cache.set("a", "A")
    +
    +  setTimeout(function () {
    +    cache.set("b", "b")
    +    t.equal(cache.get("a"), "A")
    +  }, 25)
    +
    +  setTimeout(function () {
    +    cache.set("c", "C")
    +    // timed out
    +    t.notOk(cache.get("a"))
    +  }, 60 + 25)
    +
    +  setTimeout(function () {
    +    t.notOk(cache.get("b"))
    +    t.equal(cache.get("c"), "C")
    +  }, 90)
    +
    +  setTimeout(function () {
    +    t.notOk(cache.get("c"))
    +    t.end()
    +  }, 155)
    +})
    +
    +test("individual item can have it's own maxAge", function(t) {
    +  var cache = new LRU({
    +    max: 5,
    +    maxAge: 50
    +  })
    +
    +  cache.set("a", "A", 20)
    +  setTimeout(function () {
    +    t.notOk(cache.get("a"))
    +    t.end()
    +  }, 25)
    +})
    +
    +test("individual item can have it's own maxAge > cache's", function(t) {
    +  var cache = new LRU({
    +    max: 5,
    +    maxAge: 20
    +  })
    +
    +  cache.set("a", "A", 50)
    +  setTimeout(function () {
    +    t.equal(cache.get("a"), "A")
    +    t.end()
    +  }, 25)
    +})
    +
    +test("disposal function", function(t) {
    +  var disposed = false
    +  var cache = new LRU({
    +    max: 1,
    +    dispose: function (k, n) {
    +      disposed = n
    +    }
    +  })
    +
    +  cache.set(1, 1)
    +  cache.set(2, 2)
    +  t.equal(disposed, 1)
    +  cache.set(3, 3)
    +  t.equal(disposed, 2)
    +  cache.reset()
    +  t.equal(disposed, 3)
    +  t.end()
    +})
    +
    +test("disposal function on too big of item", function(t) {
    +  var disposed = false
    +  var cache = new LRU({
    +    max: 1,
    +    length: function (k) {
    +      return k.length
    +    },
    +    dispose: function (k, n) {
    +      disposed = n
    +    }
    +  })
    +  var obj = [ 1, 2 ]
    +
    +  t.equal(disposed, false)
    +  cache.set("obj", obj)
    +  t.equal(disposed, obj)
    +  t.end()
    +})
    +
    +test("has()", function(t) {
    +  var cache = new LRU({
    +    max: 1,
    +    maxAge: 10
    +  })
    +
    +  cache.set('foo', 'bar')
    +  t.equal(cache.has('foo'), true)
    +  cache.set('blu', 'baz')
    +  t.equal(cache.has('foo'), false)
    +  t.equal(cache.has('blu'), true)
    +  setTimeout(function() {
    +    t.equal(cache.has('blu'), false)
    +    t.end()
    +  }, 15)
    +})
    +
    +test("stale", function(t) {
    +  var cache = new LRU({
    +    maxAge: 10,
    +    stale: true
    +  })
    +
    +  cache.set('foo', 'bar')
    +  t.equal(cache.get('foo'), 'bar')
    +  t.equal(cache.has('foo'), true)
    +  setTimeout(function() {
    +    t.equal(cache.has('foo'), false)
    +    t.equal(cache.get('foo'), 'bar')
    +    t.equal(cache.get('foo'), undefined)
    +    t.end()
    +  }, 15)
    +})
    +
    +test("lru update via set", function(t) {
    +  var cache = LRU({ max: 2 });
    +
    +  cache.set('foo', 1);
    +  cache.set('bar', 2);
    +  cache.del('bar');
    +  cache.set('baz', 3);
    +  cache.set('qux', 4);
    +
    +  t.equal(cache.get('foo'), undefined)
    +  t.equal(cache.get('bar'), undefined)
    +  t.equal(cache.get('baz'), 3)
    +  t.equal(cache.get('qux'), 4)
    +  t.end()
    +})
    +
    +test("least recently set w/ peek", function (t) {
    +  var cache = new LRU(2)
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +  t.equal(cache.peek("a"), "A")
    +  cache.set("c", "C")
    +  t.equal(cache.get("c"), "C")
    +  t.equal(cache.get("b"), "B")
    +  t.equal(cache.get("a"), undefined)
    +  t.end()
    +})
    +
    +test("pop the least used item", function (t) {
    +  var cache = new LRU(3)
    +  , last
    +
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +  cache.set("c", "C")
    +
    +  t.equal(cache.length, 3)
    +  t.equal(cache.max, 3)
    +
    +  // Ensure we pop a, c, b
    +  cache.get("b", "B")
    +
    +  last = cache.pop()
    +  t.equal(last.key, "a")
    +  t.equal(last.value, "A")
    +  t.equal(cache.length, 2)
    +  t.equal(cache.max, 3)
    +
    +  last = cache.pop()
    +  t.equal(last.key, "c")
    +  t.equal(last.value, "C")
    +  t.equal(cache.length, 1)
    +  t.equal(cache.max, 3)
    +
    +  last = cache.pop()
    +  t.equal(last.key, "b")
    +  t.equal(last.value, "B")
    +  t.equal(cache.length, 0)
    +  t.equal(cache.max, 3)
    +
    +  last = cache.pop()
    +  t.equal(last, null)
    +  t.equal(cache.length, 0)
    +  t.equal(cache.max, 3)
    +
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
    new file mode 100644
    index 0000000..4190417
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/foreach.js
    @@ -0,0 +1,120 @@
    +var test = require('tap').test
    +var LRU = require('../')
    +
    +test('forEach', function (t) {
    +  var l = new LRU(5)
    +  for (var i = 0; i < 10; i ++) {
    +    l.set(i.toString(), i.toString(2))
    +  }
    +
    +  var i = 9
    +  l.forEach(function (val, key, cache) {
    +    t.equal(cache, l)
    +    t.equal(key, i.toString())
    +    t.equal(val, i.toString(2))
    +    i -= 1
    +  })
    +
    +  // get in order of most recently used
    +  l.get(6)
    +  l.get(8)
    +
    +  var order = [ 8, 6, 9, 7, 5 ]
    +  var i = 0
    +
    +  l.forEach(function (val, key, cache) {
    +    var j = order[i ++]
    +    t.equal(cache, l)
    +    t.equal(key, j.toString())
    +    t.equal(val, j.toString(2))
    +  })
    +  t.equal(i, order.length);
    +
    +  t.end()
    +})
    +
    +test('keys() and values()', function (t) {
    +  var l = new LRU(5)
    +  for (var i = 0; i < 10; i ++) {
    +    l.set(i.toString(), i.toString(2))
    +  }
    +
    +  t.similar(l.keys(), ['9', '8', '7', '6', '5'])
    +  t.similar(l.values(), ['1001', '1000', '111', '110', '101'])
    +
    +  // get in order of most recently used
    +  l.get(6)
    +  l.get(8)
    +
    +  t.similar(l.keys(), ['8', '6', '9', '7', '5'])
    +  t.similar(l.values(), ['1000', '110', '1001', '111', '101'])
    +
    +  t.end()
    +})
    +
    +test('all entries are iterated over', function(t) {
    +  var l = new LRU(5)
    +  for (var i = 0; i < 10; i ++) {
    +    l.set(i.toString(), i.toString(2))
    +  }
    +
    +  var i = 0
    +  l.forEach(function (val, key, cache) {
    +    if (i > 0) {
    +      cache.del(key)
    +    }
    +    i += 1
    +  })
    +
    +  t.equal(i, 5)
    +  t.equal(l.keys().length, 1)
    +
    +  t.end()
    +})
    +
    +test('all stale entries are removed', function(t) {
    +  var l = new LRU({ max: 5, maxAge: -5, stale: true })
    +  for (var i = 0; i < 10; i ++) {
    +    l.set(i.toString(), i.toString(2))
    +  }
    +
    +  var i = 0
    +  l.forEach(function () {
    +    i += 1
    +  })
    +
    +  t.equal(i, 5)
    +  t.equal(l.keys().length, 0)
    +
    +  t.end()
    +})
    +
    +test('expires', function (t) {
    +  var l = new LRU({
    +    max: 10,
    +    maxAge: 50
    +  })
    +  for (var i = 0; i < 10; i++) {
    +    l.set(i.toString(), i.toString(2), ((i % 2) ? 25 : undefined))
    +  }
    +
    +  var i = 0
    +  var order = [ 8, 6, 4, 2, 0 ]
    +  setTimeout(function () {
    +    l.forEach(function (val, key, cache) {
    +      var j = order[i++]
    +      t.equal(cache, l)
    +      t.equal(key, j.toString())
    +      t.equal(val, j.toString(2))
    +    })
    +    t.equal(i, order.length);
    +
    +    setTimeout(function () {
    +      var count = 0;
    +      l.forEach(function (val, key, cache) { count++; })
    +      t.equal(0, count);
    +      t.end()
    +    }, 25)
    +
    +  }, 26)
    +})
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
    new file mode 100644
    index 0000000..b5912f6
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js
    @@ -0,0 +1,51 @@
    +#!/usr/bin/env node --expose_gc
    +
    +
    +var weak = require('weak');
    +var test = require('tap').test
    +var LRU = require('../')
    +var l = new LRU({ max: 10 })
    +var refs = 0
    +function X() {
    +  refs ++
    +  weak(this, deref)
    +}
    +
    +function deref() {
    +  refs --
    +}
    +
    +test('no leaks', function (t) {
    +  // fill up the cache
    +  for (var i = 0; i < 100; i++) {
    +    l.set(i, new X);
    +    // throw some gets in there, too.
    +    if (i % 2 === 0)
    +      l.get(i / 2)
    +  }
    +
    +  gc()
    +
    +  var start = process.memoryUsage()
    +
    +  // capture the memory
    +  var startRefs = refs
    +
    +  // do it again, but more
    +  for (var i = 0; i < 10000; i++) {
    +    l.set(i, new X);
    +    // throw some gets in there, too.
    +    if (i % 2 === 0)
    +      l.get(i / 2)
    +  }
    +
    +  gc()
    +
    +  var end = process.memoryUsage()
    +  t.equal(refs, startRefs, 'no leaky refs')
    +
    +  console.error('start: %j\n' +
    +                'end:   %j', start, end);
    +  t.pass();
    +  t.end();
    +})
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/serialize.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/serialize.js
    new file mode 100644
    index 0000000..1094194
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/lru-cache/test/serialize.js
    @@ -0,0 +1,216 @@
    +var test = require('tap').test
    +var LRU = require('../')
    +
    +test('dump', function (t) {
    +  var cache = new LRU()
    +
    +  t.equal(cache.dump().length, 0, "nothing in dump for empty cache")
    +
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +  t.deepEqual(cache.dump(), [
    +    { k: "b", v: "B", e: 0 },
    +    { k: "a", v: "A", e: 0 }
    +  ])
    +
    +  cache.set("a", "A");
    +  t.deepEqual(cache.dump(), [
    +    { k: "a", v: "A", e: 0 },
    +    { k: "b", v: "B", e: 0 }
    +  ])
    +
    +  cache.get("b");
    +  t.deepEqual(cache.dump(), [
    +    { k: "b", v: "B", e: 0 },
    +    { k: "a", v: "A", e: 0 }
    +  ])
    +
    +  cache.del("a");
    +  t.deepEqual(cache.dump(), [
    +    { k: "b", v: "B",  e: 0 }
    +  ])
    +
    +  t.end()
    +})
    +
    +test("do not dump stale items", function(t) {
    +  var cache = new LRU({
    +    max: 5,
    +    maxAge: 50
    +  })
    +
    +  //expires at 50
    +  cache.set("a", "A")
    +
    +  setTimeout(function () {
    +    //expires at 75
    +    cache.set("b", "B")
    +    var s = cache.dump()
    +    t.equal(s.length, 2)
    +    t.equal(s[0].k, "b")
    +    t.equal(s[1].k, "a")
    +  }, 25)
    +
    +  setTimeout(function () {
    +    //expires at 110
    +    cache.set("c", "C")
    +    var s = cache.dump()
    +    t.equal(s.length, 2)
    +    t.equal(s[0].k, "c")
    +    t.equal(s[1].k, "b")
    +  }, 60)
    +
    +  setTimeout(function () {
    +    //expires at 130
    +    cache.set("d", "D", 40)
    +    var s = cache.dump()
    +    t.equal(s.length, 2)
    +    t.equal(s[0].k, "d")
    +    t.equal(s[1].k, "c")
    +  }, 90)
    +
    +  setTimeout(function () {
    +    var s = cache.dump()
    +    t.equal(s.length, 1)
    +    t.equal(s[0].k, "d")
    +  }, 120)
    +
    +  setTimeout(function () {
    +    var s = cache.dump()
    +    t.deepEqual(s, [])
    +    t.end()
    +  }, 155)
    +})
    +
    +test("load basic cache", function(t) {
    +  var cache = new LRU(),
    +      copy = new LRU()
    +
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +
    +  copy.load(cache.dump())
    +  t.deepEquals(cache.dump(), copy.dump())
    +
    +  t.end()
    +})
    +
    +
    +test("load staled cache", function(t) {
    +  var cache = new LRU({maxAge: 50}),
    +      copy = new LRU({maxAge: 50}),
    +      arr
    +
    +  //expires at 50
    +  cache.set("a", "A")
    +  setTimeout(function () {
    +    //expires at 80
    +    cache.set("b", "B")
    +    arr = cache.dump()
    +    t.equal(arr.length, 2)
    +  }, 30)
    +
    +  setTimeout(function () {
    +    copy.load(arr)
    +    t.equal(copy.get("a"), undefined)
    +    t.equal(copy.get("b"), "B")
    +  }, 60)
    +
    +  setTimeout(function () {
    +    t.equal(copy.get("b"), undefined)
    +    t.end()
    +  }, 90)
    +})
    +
    +test("load to other size cache", function(t) {
    +  var cache = new LRU({max: 2}),
    +      copy = new LRU({max: 1})
    +
    +  cache.set("a", "A")
    +  cache.set("b", "B")
    +
    +  copy.load(cache.dump())
    +  t.equal(copy.get("a"), undefined)
    +  t.equal(copy.get("b"), "B")
    +
    +  //update the last read from original cache
    +  cache.get("a")
    +  copy.load(cache.dump())
    +  t.equal(copy.get("a"), "A")
    +  t.equal(copy.get("b"), undefined)
    +
    +  t.end()
    +})
    +
    +
    +test("load to other age cache", function(t) {
    +  var cache = new LRU({maxAge: 50}),
    +      aged = new LRU({maxAge: 100}),
    +      simple = new LRU(),
    +      arr,
    +      expired
    +
    +  //created at 0
    +  //a would be valid till 0 + 50
    +  cache.set("a", "A")
    +  setTimeout(function () {
    +    //created at 20
    +    //b would be valid till 20 + 50
    +    cache.set("b", "B")
    +    //b would be valid till 20 + 70
    +    cache.set("c", "C", 70)
    +    arr = cache.dump()
    +    t.equal(arr.length, 3)
    +  }, 20)
    +
    +  setTimeout(function () {
    +    t.equal(cache.get("a"), undefined)
    +    t.equal(cache.get("b"), "B")
    +    t.equal(cache.get("c"), "C")
    +
    +    aged.load(arr)
    +    t.equal(aged.get("a"), undefined)
    +    t.equal(aged.get("b"), "B")
    +    t.equal(aged.get("c"), "C")
    +
    +    simple.load(arr)
    +    t.equal(simple.get("a"), undefined)
    +    t.equal(simple.get("b"), "B")
    +    t.equal(simple.get("c"), "C")
    +  }, 60)
    +
    +  setTimeout(function () {
    +    t.equal(cache.get("a"), undefined)
    +    t.equal(cache.get("b"), undefined)
    +    t.equal(cache.get("c"), "C")
    +
    +    aged.load(arr)
    +    t.equal(aged.get("a"), undefined)
    +    t.equal(aged.get("b"), undefined)
    +    t.equal(aged.get("c"), "C")
    +
    +    simple.load(arr)
    +    t.equal(simple.get("a"), undefined)
    +    t.equal(simple.get("b"), undefined)
    +    t.equal(simple.get("c"), "C")
    +  }, 80)
    +
    +  setTimeout(function () {
    +    t.equal(cache.get("a"), undefined)
    +    t.equal(cache.get("b"), undefined)
    +    t.equal(cache.get("c"), undefined)
    +
    +    aged.load(arr)
    +    t.equal(aged.get("a"), undefined)
    +    t.equal(aged.get("b"), undefined)
    +    t.equal(aged.get("c"), undefined)
    +
    +    simple.load(arr)
    +    t.equal(simple.get("a"), undefined)
    +    t.equal(simple.get("b"), undefined)
    +    t.equal(simple.get("c"), undefined)
    +    t.end()
    +  }, 100)
    +
    +})
    +
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
    new file mode 100644
    index 0000000..19129e3
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/LICENSE
    @@ -0,0 +1,15 @@
    +The ISC License
    +
    +Copyright (c) Isaac Z. Schlueter and Contributors
    +
    +Permission to use, copy, modify, and/or distribute this software for any
    +purpose with or without fee is hereby granted, provided that the above
    +copyright notice and this permission notice appear in all copies.
    +
    +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
    +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
    new file mode 100644
    index 0000000..25a38a5
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/README.md
    @@ -0,0 +1,53 @@
    +# sigmund
    +
    +Quick and dirty signatures for Objects.
    +
    +This is like a much faster `deepEquals` comparison, which returns a
    +string key suitable for caches and the like.
    +
    +## Usage
    +
    +```javascript
    +function doSomething (someObj) {
    +  var key = sigmund(someObj, maxDepth) // max depth defaults to 10
    +  var cached = cache.get(key)
    +  if (cached) return cached
    +
    +  var result = expensiveCalculation(someObj)
    +  cache.set(key, result)
    +  return result
    +}
    +```
    +
    +The resulting key will be as unique and reproducible as calling
    +`JSON.stringify` or `util.inspect` on the object, but is much faster.
    +In order to achieve this speed, some differences are glossed over.
    +For example, the object `{0:'foo'}` will be treated identically to the
    +array `['foo']`.
    +
    +Also, just as there is no way to summon the soul from the scribblings
    +of a cocaine-addled psychoanalyst, there is no way to revive the object
    +from the signature string that sigmund gives you.  In fact, it's
    +barely even readable.
    +
    +As with `util.inspect` and `JSON.stringify`, larger objects will
    +produce larger signature strings.
    +
    +Because sigmund is a bit less strict than the more thorough
    +alternatives, the strings will be shorter, and also there is a
    +slightly higher chance for collisions.  For example, these objects
    +have the same signature:
    +
    +    var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
    +    var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
    +
    +Like a good Freudian, sigmund is most effective when you already have
    +some understanding of what you're looking for.  It can help you help
    +yourself, but you must be willing to do some work as well.
    +
    +Cycles are handled, and cyclical objects are silently omitted (though
    +the key is included in the signature output.)
    +
    +The second argument is the maximum depth, which defaults to 10,
    +because that is the maximum object traversal depth covered by most
    +insurance carriers.
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
    new file mode 100644
    index 0000000..5acfd6d
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/bench.js
    @@ -0,0 +1,283 @@
    +// different ways to id objects
    +// use a req/res pair, since it's crazy deep and cyclical
    +
    +// sparseFE10 and sigmund are usually pretty close, which is to be expected,
    +// since they are essentially the same algorithm, except that sigmund handles
    +// regular expression objects properly.
    +
    +
    +var http = require('http')
    +var util = require('util')
    +var sigmund = require('./sigmund.js')
    +var sreq, sres, creq, cres, test
    +
    +http.createServer(function (q, s) {
    +  sreq = q
    +  sres = s
    +  sres.end('ok')
    +  this.close(function () { setTimeout(function () {
    +    start()
    +  }, 200) })
    +}).listen(1337, function () {
    +  creq = http.get({ port: 1337 })
    +  creq.on('response', function (s) { cres = s })
    +})
    +
    +function start () {
    +  test = [sreq, sres, creq, cres]
    +  // test = sreq
    +  // sreq.sres = sres
    +  // sreq.creq = creq
    +  // sreq.cres = cres
    +
    +  for (var i in exports.compare) {
    +    console.log(i)
    +    var hash = exports.compare[i]()
    +    console.log(hash)
    +    console.log(hash.length)
    +    console.log('')
    +  }
    +
    +  require('bench').runMain()
    +}
    +
    +function customWs (obj, md, d) {
    +  d = d || 0
    +  var to = typeof obj
    +  if (to === 'undefined' || to === 'function' || to === null) return ''
    +  if (d > md || !obj || to !== 'object') return ('' + obj).replace(/[\n ]+/g, '')
    +
    +  if (Array.isArray(obj)) {
    +    return obj.map(function (i, _, __) {
    +      return customWs(i, md, d + 1)
    +    }).reduce(function (a, b) { return a + b }, '')
    +  }
    +
    +  var keys = Object.keys(obj)
    +  return keys.map(function (k, _, __) {
    +    return k + ':' + customWs(obj[k], md, d + 1)
    +  }).reduce(function (a, b) { return a + b }, '')
    +}
    +
    +function custom (obj, md, d) {
    +  d = d || 0
    +  var to = typeof obj
    +  if (to === 'undefined' || to === 'function' || to === null) return ''
    +  if (d > md || !obj || to !== 'object') return '' + obj
    +
    +  if (Array.isArray(obj)) {
    +    return obj.map(function (i, _, __) {
    +      return custom(i, md, d + 1)
    +    }).reduce(function (a, b) { return a + b }, '')
    +  }
    +
    +  var keys = Object.keys(obj)
    +  return keys.map(function (k, _, __) {
    +    return k + ':' + custom(obj[k], md, d + 1)
    +  }).reduce(function (a, b) { return a + b }, '')
    +}
    +
    +function sparseFE2 (obj, maxDepth) {
    +  var seen = []
    +  var soFar = ''
    +  function ch (v, depth) {
    +    if (depth > maxDepth) return
    +    if (typeof v === 'function' || typeof v === 'undefined') return
    +    if (typeof v !== 'object' || !v) {
    +      soFar += v
    +      return
    +    }
    +    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
    +    seen.push(v)
    +    soFar += '{'
    +    Object.keys(v).forEach(function (k, _, __) {
    +      // pseudo-private values.  skip those.
    +      if (k.charAt(0) === '_') return
    +      var to = typeof v[k]
    +      if (to === 'function' || to === 'undefined') return
    +      soFar += k + ':'
    +      ch(v[k], depth + 1)
    +    })
    +    soFar += '}'
    +  }
    +  ch(obj, 0)
    +  return soFar
    +}
    +
    +function sparseFE (obj, maxDepth) {
    +  var seen = []
    +  var soFar = ''
    +  function ch (v, depth) {
    +    if (depth > maxDepth) return
    +    if (typeof v === 'function' || typeof v === 'undefined') return
    +    if (typeof v !== 'object' || !v) {
    +      soFar += v
    +      return
    +    }
    +    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
    +    seen.push(v)
    +    soFar += '{'
    +    Object.keys(v).forEach(function (k, _, __) {
    +      // pseudo-private values.  skip those.
    +      if (k.charAt(0) === '_') return
    +      var to = typeof v[k]
    +      if (to === 'function' || to === 'undefined') return
    +      soFar += k
    +      ch(v[k], depth + 1)
    +    })
    +  }
    +  ch(obj, 0)
    +  return soFar
    +}
    +
    +function sparse (obj, maxDepth) {
    +  var seen = []
    +  var soFar = ''
    +  function ch (v, depth) {
    +    if (depth > maxDepth) return
    +    if (typeof v === 'function' || typeof v === 'undefined') return
    +    if (typeof v !== 'object' || !v) {
    +      soFar += v
    +      return
    +    }
    +    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
    +    seen.push(v)
    +    soFar += '{'
    +    for (var k in v) {
    +      // pseudo-private values.  skip those.
    +      if (k.charAt(0) === '_') continue
    +      var to = typeof v[k]
    +      if (to === 'function' || to === 'undefined') continue
    +      soFar += k
    +      ch(v[k], depth + 1)
    +    }
    +  }
    +  ch(obj, 0)
    +  return soFar
    +}
    +
    +function noCommas (obj, maxDepth) {
    +  var seen = []
    +  var soFar = ''
    +  function ch (v, depth) {
    +    if (depth > maxDepth) return
    +    if (typeof v === 'function' || typeof v === 'undefined') return
    +    if (typeof v !== 'object' || !v) {
    +      soFar += v
    +      return
    +    }
    +    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
    +    seen.push(v)
    +    soFar += '{'
    +    for (var k in v) {
    +      // pseudo-private values.  skip those.
    +      if (k.charAt(0) === '_') continue
    +      var to = typeof v[k]
    +      if (to === 'function' || to === 'undefined') continue
    +      soFar += k + ':'
    +      ch(v[k], depth + 1)
    +    }
    +    soFar += '}'
    +  }
    +  ch(obj, 0)
    +  return soFar
    +}
    +
    +
    +function flatten (obj, maxDepth) {
    +  var seen = []
    +  var soFar = ''
    +  function ch (v, depth) {
    +    if (depth > maxDepth) return
    +    if (typeof v === 'function' || typeof v === 'undefined') return
    +    if (typeof v !== 'object' || !v) {
    +      soFar += v
    +      return
    +    }
    +    if (seen.indexOf(v) !== -1 || depth === maxDepth) return
    +    seen.push(v)
    +    soFar += '{'
    +    for (var k in v) {
    +      // pseudo-private values.  skip those.
    +      if (k.charAt(0) === '_') continue
    +      var to = typeof v[k]
    +      if (to === 'function' || to === 'undefined') continue
    +      soFar += k + ':'
    +      ch(v[k], depth + 1)
    +      soFar += ','
    +    }
    +    soFar += '}'
    +  }
    +  ch(obj, 0)
    +  return soFar
    +}
    +
    +exports.compare =
    +{
    +  // 'custom 2': function () {
    +  //   return custom(test, 2, 0)
    +  // },
    +  // 'customWs 2': function () {
    +  //   return customWs(test, 2, 0)
    +  // },
    +  'JSON.stringify (guarded)': function () {
    +    var seen = []
    +    return JSON.stringify(test, function (k, v) {
    +      if (typeof v !== 'object' || !v) return v
    +      if (seen.indexOf(v) !== -1) return undefined
    +      seen.push(v)
    +      return v
    +    })
    +  },
    +
    +  'flatten 10': function () {
    +    return flatten(test, 10)
    +  },
    +
    +  // 'flattenFE 10': function () {
    +  //   return flattenFE(test, 10)
    +  // },
    +
    +  'noCommas 10': function () {
    +    return noCommas(test, 10)
    +  },
    +
    +  'sparse 10': function () {
    +    return sparse(test, 10)
    +  },
    +
    +  'sparseFE 10': function () {
    +    return sparseFE(test, 10)
    +  },
    +
    +  'sparseFE2 10': function () {
    +    return sparseFE2(test, 10)
    +  },
    +
    +  sigmund: function() {
    +    return sigmund(test, 10)
    +  },
    +
    +
    +  // 'util.inspect 1': function () {
    +  //   return util.inspect(test, false, 1, false)
    +  // },
    +  // 'util.inspect undefined': function () {
    +  //   util.inspect(test)
    +  // },
    +  // 'util.inspect 2': function () {
    +  //   util.inspect(test, false, 2, false)
    +  // },
    +  // 'util.inspect 3': function () {
    +  //   util.inspect(test, false, 3, false)
    +  // },
    +  // 'util.inspect 4': function () {
    +  //   util.inspect(test, false, 4, false)
    +  // },
    +  // 'util.inspect Infinity': function () {
    +  //   util.inspect(test, false, Infinity, false)
    +  // }
    +}
    +
    +/** results
    +**/
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
    new file mode 100644
    index 0000000..546c28c
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/package.json
    @@ -0,0 +1,60 @@
    +{
    +  "name": "sigmund",
    +  "version": "1.0.1",
    +  "description": "Quick and dirty signatures for Objects.",
    +  "main": "sigmund.js",
    +  "directories": {
    +    "test": "test"
    +  },
    +  "dependencies": {},
    +  "devDependencies": {
    +    "tap": "~0.3.0"
    +  },
    +  "scripts": {
    +    "test": "tap test/*.js",
    +    "bench": "node bench.js"
    +  },
    +  "repository": {
    +    "type": "git",
    +    "url": "git://github.com/isaacs/sigmund.git"
    +  },
    +  "keywords": [
    +    "object",
    +    "signature",
    +    "key",
    +    "data",
    +    "psychoanalysis"
    +  ],
    +  "author": {
    +    "name": "Isaac Z. Schlueter",
    +    "email": "i@izs.me",
    +    "url": "http://blog.izs.me/"
    +  },
    +  "license": "ISC",
    +  "gitHead": "527f97aa5bb253d927348698c0cd3bb267d098c6",
    +  "bugs": {
    +    "url": "https://github.com/isaacs/sigmund/issues"
    +  },
    +  "homepage": "https://github.com/isaacs/sigmund#readme",
    +  "_id": "sigmund@1.0.1",
    +  "_shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
    +  "_from": "sigmund@>=1.0.0 <1.1.0",
    +  "_npmVersion": "2.10.0",
    +  "_nodeVersion": "2.0.1",
    +  "_npmUser": {
    +    "name": "isaacs",
    +    "email": "isaacs@npmjs.com"
    +  },
    +  "dist": {
    +    "shasum": "3ff21f198cad2175f9f3b781853fd94d0d19b590",
    +    "tarball": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz"
    +  },
    +  "maintainers": [
    +    {
    +      "name": "isaacs",
    +      "email": "i@izs.me"
    +    }
    +  ],
    +  "_resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
    new file mode 100644
    index 0000000..82c7ab8
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/sigmund.js
    @@ -0,0 +1,39 @@
    +module.exports = sigmund
    +function sigmund (subject, maxSessions) {
    +    maxSessions = maxSessions || 10;
    +    var notes = [];
    +    var analysis = '';
    +    var RE = RegExp;
    +
    +    function psychoAnalyze (subject, session) {
    +        if (session > maxSessions) return;
    +
    +        if (typeof subject === 'function' ||
    +            typeof subject === 'undefined') {
    +            return;
    +        }
    +
    +        if (typeof subject !== 'object' || !subject ||
    +            (subject instanceof RE)) {
    +            analysis += subject;
    +            return;
    +        }
    +
    +        if (notes.indexOf(subject) !== -1 || session === maxSessions) return;
    +
    +        notes.push(subject);
    +        analysis += '{';
    +        Object.keys(subject).forEach(function (issue, _, __) {
    +            // pseudo-private values.  skip those.
    +            if (issue.charAt(0) === '_') return;
    +            var to = typeof subject[issue];
    +            if (to === 'function' || to === 'undefined') return;
    +            analysis += issue;
    +            psychoAnalyze(subject[issue], session + 1);
    +        });
    +    }
    +    psychoAnalyze(subject, 0);
    +    return analysis;
    +}
    +
    +// vim: set softtabstop=4 shiftwidth=4:
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
    new file mode 100644
    index 0000000..50c53a1
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/node_modules/sigmund/test/basic.js
    @@ -0,0 +1,24 @@
    +var test = require('tap').test
    +var sigmund = require('../sigmund.js')
    +
    +
    +// occasionally there are duplicates
    +// that's an acceptable edge-case.  JSON.stringify and util.inspect
    +// have some collision potential as well, though less, and collision
    +// detection is expensive.
    +var hash = '{abc/def/g{0h1i2{jkl'
    +var obj1 = {a:'b',c:/def/,g:['h','i',{j:'',k:'l'}]}
    +var obj2 = {a:'b',c:'/def/',g:['h','i','{jkl']}
    +
    +var obj3 = JSON.parse(JSON.stringify(obj1))
    +obj3.c = /def/
    +obj3.g[2].cycle = obj3
    +var cycleHash = '{abc/def/g{0h1i2{jklcycle'
    +
    +test('basic', function (t) {
    +    t.equal(sigmund(obj1), hash)
    +    t.equal(sigmund(obj2), hash)
    +    t.equal(sigmund(obj3), cycleHash)
    +    t.end()
    +})
    +
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/package.json b/node_modules/mocha/node_modules/glob/node_modules/minimatch/package.json
    new file mode 100644
    index 0000000..68b547b
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/package.json
    @@ -0,0 +1,58 @@
    +{
    +  "author": {
    +    "name": "Isaac Z. Schlueter",
    +    "email": "i@izs.me",
    +    "url": "http://blog.izs.me"
    +  },
    +  "name": "minimatch",
    +  "description": "a glob matcher in javascript",
    +  "version": "0.3.0",
    +  "repository": {
    +    "type": "git",
    +    "url": "git://github.com/isaacs/minimatch.git"
    +  },
    +  "main": "minimatch.js",
    +  "scripts": {
    +    "test": "tap test/*.js"
    +  },
    +  "engines": {
    +    "node": "*"
    +  },
    +  "dependencies": {
    +    "lru-cache": "2",
    +    "sigmund": "~1.0.0"
    +  },
    +  "devDependencies": {
    +    "tap": ""
    +  },
    +  "license": {
    +    "type": "MIT",
    +    "url": "http://github.com/isaacs/minimatch/raw/master/LICENSE"
    +  },
    +  "bugs": {
    +    "url": "https://github.com/isaacs/minimatch/issues"
    +  },
    +  "homepage": "https://github.com/isaacs/minimatch",
    +  "_id": "minimatch@0.3.0",
    +  "_shasum": "275d8edaac4f1bb3326472089e7949c8394699dd",
    +  "_from": "minimatch@>=0.3.0 <0.4.0",
    +  "_npmVersion": "1.4.10",
    +  "_npmUser": {
    +    "name": "isaacs",
    +    "email": "i@izs.me"
    +  },
    +  "maintainers": [
    +    {
    +      "name": "isaacs",
    +      "email": "i@izs.me"
    +    }
    +  ],
    +  "dist": {
    +    "shasum": "275d8edaac4f1bb3326472089e7949c8394699dd",
    +    "tarball": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz"
    +  },
    +  "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue",
    +  "directories": {},
    +  "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/basic.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/basic.js
    new file mode 100644
    index 0000000..ae7ac73
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/basic.js
    @@ -0,0 +1,399 @@
    +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
    +//
    +// TODO: Some of these tests do very bad things with backslashes, and will
    +// most likely fail badly on windows.  They should probably be skipped.
    +
    +var tap = require("tap")
    +  , globalBefore = Object.keys(global)
    +  , mm = require("../")
    +  , files = [ "a", "b", "c", "d", "abc"
    +            , "abd", "abe", "bb", "bcd"
    +            , "ca", "cb", "dd", "de"
    +            , "bdir/", "bdir/cfile"]
    +  , next = files.concat([ "a-b", "aXb"
    +                        , ".x", ".y" ])
    +
    +
    +var patterns =
    +  [ "http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test"
    +  , ["a*", ["a", "abc", "abd", "abe"]]
    +  , ["X*", ["X*"], {nonull: true}]
    +
    +  // allow null glob expansion
    +  , ["X*", []]
    +
    +  // isaacs: Slightly different than bash/sh/ksh
    +  // \\* is not un-escaped to literal "*" in a failed match,
    +  // but it does make it get treated as a literal star
    +  , ["\\*", ["\\*"], {nonull: true}]
    +  , ["\\**", ["\\**"], {nonull: true}]
    +  , ["\\*\\*", ["\\*\\*"], {nonull: true}]
    +
    +  , ["b*/", ["bdir/"]]
    +  , ["c*", ["c", "ca", "cb"]]
    +  , ["**", files]
    +
    +  , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
    +  , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
    +
    +  , "legendary larry crashes bashes"
    +  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
    +    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
    +  , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
    +    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
    +
    +  , "character classes"
    +  , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
    +  , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
    +     "bdir/", "ca", "cb", "dd", "de"]]
    +  , ["a*[^c]", ["abd", "abe"]]
    +  , function () { files.push("a-b", "aXb") }
    +  , ["a[X-]b", ["a-b", "aXb"]]
    +  , function () { files.push(".x", ".y") }
    +  , ["[^a-c]*", ["d", "dd", "de"]]
    +  , function () { files.push("a*b/", "a*b/ooo") }
    +  , ["a\\*b/*", ["a*b/ooo"]]
    +  , ["a\\*?/*", ["a*b/ooo"]]
    +  , ["*\\\\!*", [], {null: true}, ["echo !7"]]
    +  , ["*\\!*", ["echo !7"], null, ["echo !7"]]
    +  , ["*.\\*", ["r.*"], null, ["r.*"]]
    +  , ["a[b]c", ["abc"]]
    +  , ["a[\\b]c", ["abc"]]
    +  , ["a?c", ["abc"]]
    +  , ["a\\*c", [], {null: true}, ["abc"]]
    +  , ["", [""], { null: true }, [""]]
    +
    +  , "http://www.opensource.apple.com/source/bash/bash-23/" +
    +    "bash/tests/glob-test"
    +  , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
    +  , ["*/man*/bash.*", ["man/man1/bash.1"]]
    +  , ["man/man1/bash.1", ["man/man1/bash.1"]]
    +  , ["a***c", ["abc"], null, ["abc"]]
    +  , ["a*****?c", ["abc"], null, ["abc"]]
    +  , ["?*****??", ["abc"], null, ["abc"]]
    +  , ["*****??", ["abc"], null, ["abc"]]
    +  , ["?*****?c", ["abc"], null, ["abc"]]
    +  , ["?***?****c", ["abc"], null, ["abc"]]
    +  , ["?***?****?", ["abc"], null, ["abc"]]
    +  , ["?***?****", ["abc"], null, ["abc"]]
    +  , ["*******c", ["abc"], null, ["abc"]]
    +  , ["*******?", ["abc"], null, ["abc"]]
    +  , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +  , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +  , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +  , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +  , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +  , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +  , ["[-abc]", ["-"], null, ["-"]]
    +  , ["[abc-]", ["-"], null, ["-"]]
    +  , ["\\", ["\\"], null, ["\\"]]
    +  , ["[\\\\]", ["\\"], null, ["\\"]]
    +  , ["[[]", ["["], null, ["["]]
    +  , ["[", ["["], null, ["["]]
    +  , ["[*", ["[abc"], null, ["[abc"]]
    +  , "a right bracket shall lose its special meaning and\n" +
    +    "represent itself in a bracket expression if it occurs\n" +
    +    "first in the list.  -- POSIX.2 2.8.3.2"
    +  , ["[]]", ["]"], null, ["]"]]
    +  , ["[]-]", ["]"], null, ["]"]]
    +  , ["[a-\z]", ["p"], null, ["p"]]
    +  , ["??**********?****?", [], { null: true }, ["abc"]]
    +  , ["??**********?****c", [], { null: true }, ["abc"]]
    +  , ["?************c****?****", [], { null: true }, ["abc"]]
    +  , ["*c*?**", [], { null: true }, ["abc"]]
    +  , ["a*****c*?**", [], { null: true }, ["abc"]]
    +  , ["a********???*******", [], { null: true }, ["abc"]]
    +  , ["[]", [], { null: true }, ["a"]]
    +  , ["[abc", [], { null: true }, ["["]]
    +
    +  , "nocase tests"
    +  , ["XYZ", ["xYz"], { nocase: true, null: true }
    +    , ["xYz", "ABC", "IjK"]]
    +  , ["ab*", ["ABC"], { nocase: true, null: true }
    +    , ["xYz", "ABC", "IjK"]]
    +  , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
    +    , ["xYz", "ABC", "IjK"]]
    +
    +  // [ pattern, [matches], MM opts, files, TAP opts]
    +  , "onestar/twostar"
    +  , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
    +  , ["{/?,*}", ["/a", "bb"], {null: true}
    +    , ["/a", "/b/b", "/a/b/c", "bb"]]
    +
    +  , "dots should not match unless requested"
    +  , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
    +
    +  // .. and . can only match patterns starting with .,
    +  // even when options.dot is set.
    +  , function () {
    +      files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
    +    }
    +  , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
    +  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
    +  , ["a/*/b", ["a/c/b"], {dot:false}]
    +  , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
    +
    +
    +  // this also tests that changing the options needs
    +  // to change the cache key, even if the pattern is
    +  // the same!
    +  , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
    +    , [ ".a/.d", "a/.d", "a/b"]]
    +
    +  , "paren sets cannot contain slashes"
    +  , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
    +
    +  // brace sets trump all else.
    +  //
    +  // invalid glob pattern.  fails on bash4 and bsdglob.
    +  // however, in this implementation, it's easier just
    +  // to do the intuitive thing, and let brace-expansion
    +  // actually come before parsing any extglob patterns,
    +  // like the documentation seems to say.
    +  //
    +  // XXX: if anyone complains about this, either fix it
    +  // or tell them to grow up and stop complaining.
    +  //
    +  // bash/bsdglob says this:
    +  // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
    +  // but we do this instead:
    +  , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
    +
    +  // test partial parsing in the presence of comment/negation chars
    +  , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
    +  , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
    +
    +  // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
    +  , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
    +    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
    +    , {}
    +    , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
    +
    +
    +  // crazy nested {,,} and *(||) tests.
    +  , function () {
    +      files = [ "a", "b", "c", "d"
    +              , "ab", "ac", "ad"
    +              , "bc", "cb"
    +              , "bc,d", "c,db", "c,d"
    +              , "d)", "(b|c", "*(b|c"
    +              , "b|c", "b|cc", "cb|c"
    +              , "x(a|b|c)", "x(a|c)"
    +              , "(a|b|c)", "(a|c)"]
    +    }
    +  , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
    +  , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
    +  // a
    +  // *(b|c)
    +  // *(b|d)
    +  , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
    +  , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
    +
    +
    +  // test various flag settings.
    +  , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
    +    , { noext: true } ]
    +  , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
    +    , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
    +  , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
    +
    +
    +  // begin channelling Boole and deMorgan...
    +  , "negation tests"
    +  , function () {
    +      files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
    +    }
    +
    +  // anything that is NOT a* matches.
    +  , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
    +
    +  // anything that IS !a* matches.
    +  , ["!a*", ["!ab", "!abc"], {nonegate: true}]
    +
    +  // anything that IS a* matches
    +  , ["!!a*", ["a!b"]]
    +
    +  // anything that is NOT !a* matches
    +  , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
    +
    +  // negation nestled within a pattern
    +  , function () {
    +      files = [ "foo.js"
    +              , "foo.bar"
    +              // can't match this one without negative lookbehind.
    +              , "foo.js.js"
    +              , "blar.js"
    +              , "foo."
    +              , "boo.js.boo" ]
    +    }
    +  , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
    +
    +  // https://github.com/isaacs/minimatch/issues/5
    +  , function () {
    +      files = [ 'a/b/.x/c'
    +              , 'a/b/.x/c/d'
    +              , 'a/b/.x/c/d/e'
    +              , 'a/b/.x'
    +              , 'a/b/.x/'
    +              , 'a/.x/b'
    +              , '.x'
    +              , '.x/'
    +              , '.x/a'
    +              , '.x/a/b'
    +              , 'a/.x/b/.x/c'
    +              , '.x/.x' ]
    +  }
    +  , ["**/.x/**", [ '.x/'
    +                 , '.x/a'
    +                 , '.x/a/b'
    +                 , 'a/.x/b'
    +                 , 'a/b/.x/'
    +                 , 'a/b/.x/c'
    +                 , 'a/b/.x/c/d'
    +                 , 'a/b/.x/c/d/e' ] ]
    +
    +  ]
    +
    +var regexps =
    +  [ '/^(?:(?=.)a[^/]*?)$/',
    +    '/^(?:(?=.)X[^/]*?)$/',
    +    '/^(?:(?=.)X[^/]*?)$/',
    +    '/^(?:\\*)$/',
    +    '/^(?:(?=.)\\*[^/]*?)$/',
    +    '/^(?:\\*\\*)$/',
    +    '/^(?:(?=.)b[^/]*?\\/)$/',
    +    '/^(?:(?=.)c[^/]*?)$/',
    +    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
    +    '/^(?:\\.\\.\\/(?!\\.)(?=.)[^/]*?\\/)$/',
    +    '/^(?:s\\/(?=.)\\.\\.[^/]*?\\/)$/',
    +    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/1\\/)$/',
    +    '/^(?:\\/\\^root:\\/\\{s\\/(?=.)\\^[^:][^/]*?:[^:][^/]*?:\\([^:]\\)[^/]*?\\.[^/]*?\\$\\/\u0001\\/)$/',
    +    '/^(?:(?!\\.)(?=.)[a-c]b[^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[a-y][^/]*?[^c])$/',
    +    '/^(?:(?=.)a[^/]*?[^c])$/',
    +    '/^(?:(?=.)a[X-]b)$/',
    +    '/^(?:(?!\\.)(?=.)[^a-c][^/]*?)$/',
    +    '/^(?:a\\*b\\/(?!\\.)(?=.)[^/]*?)$/',
    +    '/^(?:(?=.)a\\*[^/]\\/(?!\\.)(?=.)[^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\\\\\![^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\![^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\.\\*)$/',
    +    '/^(?:(?=.)a[b]c)$/',
    +    '/^(?:(?=.)a[b]c)$/',
    +    '/^(?:(?=.)a[^/]c)$/',
    +    '/^(?:a\\*c)$/',
    +    'false',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\/(?=.)man[^/]*?\\/(?=.)bash\\.[^/]*?)$/',
    +    '/^(?:man\\/man1\\/bash\\.1)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?c)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/])$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]c)$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
    +    '/^(?:(?=.)a[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/]k[^/]*?[^/]*?[^/]*?)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/][^/]*?[^/]*?cd[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?k[^/]*?[^/]*?)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[-abc])$/',
    +    '/^(?:(?!\\.)(?=.)[abc-])$/',
    +    '/^(?:\\\\)$/',
    +    '/^(?:(?!\\.)(?=.)[\\\\])$/',
    +    '/^(?:(?!\\.)(?=.)[\\[])$/',
    +    '/^(?:\\[)$/',
    +    '/^(?:(?=.)\\[(?!\\.)(?=.)[^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[\\]])$/',
    +    '/^(?:(?!\\.)(?=.)[\\]-])$/',
    +    '/^(?:(?!\\.)(?=.)[a-z])$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/])$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?c)$/',
    +    '/^(?:(?!\\.)(?=.)[^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/]*?[^/]*?[^/]*?[^/]*?)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?c[^/]*?[^/][^/]*?[^/]*?)$/',
    +    '/^(?:(?=.)a[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/][^/][^/][^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?[^/]*?)$/',
    +    '/^(?:\\[\\])$/',
    +    '/^(?:\\[abc)$/',
    +    '/^(?:(?=.)XYZ)$/i',
    +    '/^(?:(?=.)ab[^/]*?)$/i',
    +    '/^(?:(?!\\.)(?=.)[ia][^/][ck])$/i',
    +    '/^(?:\\/(?!\\.)(?=.)[^/]*?|(?!\\.)(?=.)[^/]*?)$/',
    +    '/^(?:\\/(?!\\.)(?=.)[^/]|(?!\\.)(?=.)[^/]*?)$/',
    +    '/^(?:(?:(?!(?:\\/|^)\\.).)*?)$/',
    +    '/^(?:a\\/(?!(?:^|\\/)\\.{1,2}(?:$|\\/))(?=.)[^/]*?\\/b)$/',
    +    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
    +    '/^(?:a\\/(?!\\.)(?=.)[^/]*?\\/b)$/',
    +    '/^(?:a\\/(?=.)\\.[^/]*?\\/b)$/',
    +    '/^(?:(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\/b\\))$/',
    +    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
    +    '/^(?:(?=.)\\[(?=.)\\!a[^/]*?)$/',
    +    '/^(?:(?=.)\\[(?=.)#a[^/]*?)$/',
    +    '/^(?:(?=.)\\+\\(a\\|[^/]*?\\|c\\\\\\\\\\|d\\\\\\\\\\|e\\\\\\\\\\\\\\\\\\|f\\\\\\\\\\\\\\\\\\|g)$/',
    +    '/^(?:(?!\\.)(?=.)(?:a|b)*|(?!\\.)(?=.)(?:a|c)*)$/',
    +    '/^(?:a|(?!\\.)(?=.)[^/]*?\\(b\\|c|d\\))$/',
    +    '/^(?:a|(?!\\.)(?=.)(?:b|c)*|(?!\\.)(?=.)(?:b|d)*)$/',
    +    '/^(?:(?!\\.)(?=.)(?:a|b|c)*|(?!\\.)(?=.)(?:a|c)*)$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\(a\\|b\\|c\\)|(?!\\.)(?=.)[^/]*?\\(a\\|c\\))$/',
    +    '/^(?:(?=.)a[^/]b)$/',
    +    '/^(?:(?=.)#[^/]*?)$/',
    +    '/^(?!^(?:(?=.)a[^/]*?)$).*$/',
    +    '/^(?:(?=.)\\!a[^/]*?)$/',
    +    '/^(?:(?=.)a[^/]*?)$/',
    +    '/^(?!^(?:(?=.)\\!a[^/]*?)$).*$/',
    +    '/^(?:(?!\\.)(?=.)[^/]*?\\.(?:(?!js)[^/]*?))$/',
    +    '/^(?:(?:(?!(?:\\/|^)\\.).)*?\\/\\.x\\/(?:(?!(?:\\/|^)\\.).)*?)$/' ]
    +var re = 0;
    +
    +tap.test("basic tests", function (t) {
    +  var start = Date.now()
    +
    +  // [ pattern, [matches], MM opts, files, TAP opts]
    +  patterns.forEach(function (c) {
    +    if (typeof c === "function") return c()
    +    if (typeof c === "string") return t.comment(c)
    +
    +    var pattern = c[0]
    +      , expect = c[1].sort(alpha)
    +      , options = c[2] || {}
    +      , f = c[3] || files
    +      , tapOpts = c[4] || {}
    +
    +    // options.debug = true
    +    var m = new mm.Minimatch(pattern, options)
    +    var r = m.makeRe()
    +    var expectRe = regexps[re++]
    +    tapOpts.re = String(r) || JSON.stringify(r)
    +    tapOpts.files = JSON.stringify(f)
    +    tapOpts.pattern = pattern
    +    tapOpts.set = m.set
    +    tapOpts.negated = m.negate
    +
    +    var actual = mm.match(f, pattern, options)
    +    actual.sort(alpha)
    +
    +    t.equivalent( actual, expect
    +                , JSON.stringify(pattern) + " " + JSON.stringify(expect)
    +                , tapOpts )
    +
    +    t.equal(tapOpts.re, expectRe, tapOpts)
    +  })
    +
    +  t.comment("time=" + (Date.now() - start) + "ms")
    +  t.end()
    +})
    +
    +tap.test("global leak test", function (t) {
    +  var globalAfter = Object.keys(global)
    +  t.equivalent(globalAfter, globalBefore, "no new globals, please")
    +  t.end()
    +})
    +
    +function alpha (a, b) {
    +  return a > b ? 1 : -1
    +}
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/brace-expand.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/brace-expand.js
    new file mode 100644
    index 0000000..7ee278a
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/brace-expand.js
    @@ -0,0 +1,33 @@
    +var tap = require("tap")
    +  , minimatch = require("../")
    +
    +tap.test("brace expansion", function (t) {
    +  // [ pattern, [expanded] ]
    +  ; [ [ "a{b,c{d,e},{f,g}h}x{y,z}"
    +      , [ "abxy"
    +        , "abxz"
    +        , "acdxy"
    +        , "acdxz"
    +        , "acexy"
    +        , "acexz"
    +        , "afhxy"
    +        , "afhxz"
    +        , "aghxy"
    +        , "aghxz" ] ]
    +    , [ "a{1..5}b"
    +      , [ "a1b"
    +        , "a2b"
    +        , "a3b"
    +        , "a4b"
    +        , "a5b" ] ]
    +    , [ "a{b}c", ["a{b}c"] ]
    +  ].forEach(function (tc) {
    +    var p = tc[0]
    +      , expect = tc[1]
    +    t.equivalent(minimatch.braceExpand(p), expect, p)
    +  })
    +  console.error("ending")
    +  t.end()
    +})
    +
    +
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/caching.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/caching.js
    new file mode 100644
    index 0000000..0fec4b0
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/caching.js
    @@ -0,0 +1,14 @@
    +var Minimatch = require("../minimatch.js").Minimatch
    +var tap = require("tap")
    +tap.test("cache test", function (t) {
    +  var mm1 = new Minimatch("a?b")
    +  var mm2 = new Minimatch("a?b")
    +  t.equal(mm1, mm2, "should get the same object")
    +  // the lru should drop it after 100 entries
    +  for (var i = 0; i < 100; i ++) {
    +    new Minimatch("a"+i)
    +  }
    +  mm2 = new Minimatch("a?b")
    +  t.notEqual(mm1, mm2, "cache should have dropped")
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/defaults.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/defaults.js
    new file mode 100644
    index 0000000..75e0571
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/defaults.js
    @@ -0,0 +1,274 @@
    +// http://www.bashcookbook.com/bashinfo/source/bash-1.14.7/tests/glob-test
    +//
    +// TODO: Some of these tests do very bad things with backslashes, and will
    +// most likely fail badly on windows.  They should probably be skipped.
    +
    +var tap = require("tap")
    +  , globalBefore = Object.keys(global)
    +  , mm = require("../")
    +  , files = [ "a", "b", "c", "d", "abc"
    +            , "abd", "abe", "bb", "bcd"
    +            , "ca", "cb", "dd", "de"
    +            , "bdir/", "bdir/cfile"]
    +  , next = files.concat([ "a-b", "aXb"
    +                        , ".x", ".y" ])
    +
    +tap.test("basic tests", function (t) {
    +  var start = Date.now()
    +
    +  // [ pattern, [matches], MM opts, files, TAP opts]
    +  ; [ "http://www.bashcookbook.com/bashinfo" +
    +      "/source/bash-1.14.7/tests/glob-test"
    +    , ["a*", ["a", "abc", "abd", "abe"]]
    +    , ["X*", ["X*"], {nonull: true}]
    +
    +    // allow null glob expansion
    +    , ["X*", []]
    +
    +    // isaacs: Slightly different than bash/sh/ksh
    +    // \\* is not un-escaped to literal "*" in a failed match,
    +    // but it does make it get treated as a literal star
    +    , ["\\*", ["\\*"], {nonull: true}]
    +    , ["\\**", ["\\**"], {nonull: true}]
    +    , ["\\*\\*", ["\\*\\*"], {nonull: true}]
    +
    +    , ["b*/", ["bdir/"]]
    +    , ["c*", ["c", "ca", "cb"]]
    +    , ["**", files]
    +
    +    , ["\\.\\./*/", ["\\.\\./*/"], {nonull: true}]
    +    , ["s/\\..*//", ["s/\\..*//"], {nonull: true}]
    +
    +    , "legendary larry crashes bashes"
    +    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"
    +      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\\1/"], {nonull: true}]
    +    , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"
    +      , ["/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/"], {nonull: true}]
    +
    +    , "character classes"
    +    , ["[a-c]b*", ["abc", "abd", "abe", "bb", "cb"]]
    +    , ["[a-y]*[^c]", ["abd", "abe", "bb", "bcd",
    +       "bdir/", "ca", "cb", "dd", "de"]]
    +    , ["a*[^c]", ["abd", "abe"]]
    +    , function () { files.push("a-b", "aXb") }
    +    , ["a[X-]b", ["a-b", "aXb"]]
    +    , function () { files.push(".x", ".y") }
    +    , ["[^a-c]*", ["d", "dd", "de"]]
    +    , function () { files.push("a*b/", "a*b/ooo") }
    +    , ["a\\*b/*", ["a*b/ooo"]]
    +    , ["a\\*?/*", ["a*b/ooo"]]
    +    , ["*\\\\!*", [], {null: true}, ["echo !7"]]
    +    , ["*\\!*", ["echo !7"], null, ["echo !7"]]
    +    , ["*.\\*", ["r.*"], null, ["r.*"]]
    +    , ["a[b]c", ["abc"]]
    +    , ["a[\\b]c", ["abc"]]
    +    , ["a?c", ["abc"]]
    +    , ["a\\*c", [], {null: true}, ["abc"]]
    +    , ["", [""], { null: true }, [""]]
    +
    +    , "http://www.opensource.apple.com/source/bash/bash-23/" +
    +      "bash/tests/glob-test"
    +    , function () { files.push("man/", "man/man1/", "man/man1/bash.1") }
    +    , ["*/man*/bash.*", ["man/man1/bash.1"]]
    +    , ["man/man1/bash.1", ["man/man1/bash.1"]]
    +    , ["a***c", ["abc"], null, ["abc"]]
    +    , ["a*****?c", ["abc"], null, ["abc"]]
    +    , ["?*****??", ["abc"], null, ["abc"]]
    +    , ["*****??", ["abc"], null, ["abc"]]
    +    , ["?*****?c", ["abc"], null, ["abc"]]
    +    , ["?***?****c", ["abc"], null, ["abc"]]
    +    , ["?***?****?", ["abc"], null, ["abc"]]
    +    , ["?***?****", ["abc"], null, ["abc"]]
    +    , ["*******c", ["abc"], null, ["abc"]]
    +    , ["*******?", ["abc"], null, ["abc"]]
    +    , ["a*cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +    , ["a**?**cd**?**??k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +    , ["a**?**cd**?**??k***", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +    , ["a**?**cd**?**??***k", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +    , ["a**?**cd**?**??***k**", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +    , ["a****c**?**??*****", ["abcdecdhjk"], null, ["abcdecdhjk"]]
    +    , ["[-abc]", ["-"], null, ["-"]]
    +    , ["[abc-]", ["-"], null, ["-"]]
    +    , ["\\", ["\\"], null, ["\\"]]
    +    , ["[\\\\]", ["\\"], null, ["\\"]]
    +    , ["[[]", ["["], null, ["["]]
    +    , ["[", ["["], null, ["["]]
    +    , ["[*", ["[abc"], null, ["[abc"]]
    +    , "a right bracket shall lose its special meaning and\n" +
    +      "represent itself in a bracket expression if it occurs\n" +
    +      "first in the list.  -- POSIX.2 2.8.3.2"
    +    , ["[]]", ["]"], null, ["]"]]
    +    , ["[]-]", ["]"], null, ["]"]]
    +    , ["[a-\z]", ["p"], null, ["p"]]
    +    , ["??**********?****?", [], { null: true }, ["abc"]]
    +    , ["??**********?****c", [], { null: true }, ["abc"]]
    +    , ["?************c****?****", [], { null: true }, ["abc"]]
    +    , ["*c*?**", [], { null: true }, ["abc"]]
    +    , ["a*****c*?**", [], { null: true }, ["abc"]]
    +    , ["a********???*******", [], { null: true }, ["abc"]]
    +    , ["[]", [], { null: true }, ["a"]]
    +    , ["[abc", [], { null: true }, ["["]]
    +
    +    , "nocase tests"
    +    , ["XYZ", ["xYz"], { nocase: true, null: true }
    +      , ["xYz", "ABC", "IjK"]]
    +    , ["ab*", ["ABC"], { nocase: true, null: true }
    +      , ["xYz", "ABC", "IjK"]]
    +    , ["[ia]?[ck]", ["ABC", "IjK"], { nocase: true, null: true }
    +      , ["xYz", "ABC", "IjK"]]
    +
    +    // [ pattern, [matches], MM opts, files, TAP opts]
    +    , "onestar/twostar"
    +    , ["{/*,*}", [], {null: true}, ["/asdf/asdf/asdf"]]
    +    , ["{/?,*}", ["/a", "bb"], {null: true}
    +      , ["/a", "/b/b", "/a/b/c", "bb"]]
    +
    +    , "dots should not match unless requested"
    +    , ["**", ["a/b"], {}, ["a/b", "a/.d", ".a/.d"]]
    +
    +    // .. and . can only match patterns starting with .,
    +    // even when options.dot is set.
    +    , function () {
    +        files = ["a/./b", "a/../b", "a/c/b", "a/.d/b"]
    +      }
    +    , ["a/*/b", ["a/c/b", "a/.d/b"], {dot: true}]
    +    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: true}]
    +    , ["a/*/b", ["a/c/b"], {dot:false}]
    +    , ["a/.*/b", ["a/./b", "a/../b", "a/.d/b"], {dot: false}]
    +
    +
    +    // this also tests that changing the options needs
    +    // to change the cache key, even if the pattern is
    +    // the same!
    +    , ["**", ["a/b","a/.d",".a/.d"], { dot: true }
    +      , [ ".a/.d", "a/.d", "a/b"]]
    +
    +    , "paren sets cannot contain slashes"
    +    , ["*(a/b)", ["*(a/b)"], {nonull: true}, ["a/b"]]
    +
    +    // brace sets trump all else.
    +    //
    +    // invalid glob pattern.  fails on bash4 and bsdglob.
    +    // however, in this implementation, it's easier just
    +    // to do the intuitive thing, and let brace-expansion
    +    // actually come before parsing any extglob patterns,
    +    // like the documentation seems to say.
    +    //
    +    // XXX: if anyone complains about this, either fix it
    +    // or tell them to grow up and stop complaining.
    +    //
    +    // bash/bsdglob says this:
    +    // , ["*(a|{b),c)}", ["*(a|{b),c)}"], {}, ["a", "ab", "ac", "ad"]]
    +    // but we do this instead:
    +    , ["*(a|{b),c)}", ["a", "ab", "ac"], {}, ["a", "ab", "ac", "ad"]]
    +
    +    // test partial parsing in the presence of comment/negation chars
    +    , ["[!a*", ["[!ab"], {}, ["[!ab", "[ab"]]
    +    , ["[#a*", ["[#ab"], {}, ["[#ab", "[ab"]]
    +
    +    // like: {a,b|c\\,d\\\|e} except it's unclosed, so it has to be escaped.
    +    , ["+(a|*\\|c\\\\|d\\\\\\|e\\\\\\\\|f\\\\\\\\\\|g"
    +      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g"]
    +      , {}
    +      , ["+(a|b\\|c\\\\|d\\\\|e\\\\\\\\|f\\\\\\\\|g", "a", "b\\c"]]
    +
    +
    +    // crazy nested {,,} and *(||) tests.
    +    , function () {
    +        files = [ "a", "b", "c", "d"
    +                , "ab", "ac", "ad"
    +                , "bc", "cb"
    +                , "bc,d", "c,db", "c,d"
    +                , "d)", "(b|c", "*(b|c"
    +                , "b|c", "b|cc", "cb|c"
    +                , "x(a|b|c)", "x(a|c)"
    +                , "(a|b|c)", "(a|c)"]
    +      }
    +    , ["*(a|{b,c})", ["a", "b", "c", "ab", "ac"]]
    +    , ["{a,*(b|c,d)}", ["a","(b|c", "*(b|c", "d)"]]
    +    // a
    +    // *(b|c)
    +    // *(b|d)
    +    , ["{a,*(b|{c,d})}", ["a","b", "bc", "cb", "c", "d"]]
    +    , ["*(a|{b|c,c})", ["a", "b", "c", "ab", "ac", "bc", "cb"]]
    +
    +
    +    // test various flag settings.
    +    , [ "*(a|{b|c,c})", ["x(a|b|c)", "x(a|c)", "(a|b|c)", "(a|c)"]
    +      , { noext: true } ]
    +    , ["a?b", ["x/y/acb", "acb/"], {matchBase: true}
    +      , ["x/y/acb", "acb/", "acb/d/e", "x/y/acb/d"] ]
    +    , ["#*", ["#a", "#b"], {nocomment: true}, ["#a", "#b", "c#d"]]
    +
    +
    +    // begin channelling Boole and deMorgan...
    +    , "negation tests"
    +    , function () {
    +        files = ["d", "e", "!ab", "!abc", "a!b", "\\!a"]
    +      }
    +
    +    // anything that is NOT a* matches.
    +    , ["!a*", ["\\!a", "d", "e", "!ab", "!abc"]]
    +
    +    // anything that IS !a* matches.
    +    , ["!a*", ["!ab", "!abc"], {nonegate: true}]
    +
    +    // anything that IS a* matches
    +    , ["!!a*", ["a!b"]]
    +
    +    // anything that is NOT !a* matches
    +    , ["!\\!a*", ["a!b", "d", "e", "\\!a"]]
    +
    +    // negation nestled within a pattern
    +    , function () {
    +        files = [ "foo.js"
    +                , "foo.bar"
    +                // can't match this one without negative lookbehind.
    +                , "foo.js.js"
    +                , "blar.js"
    +                , "foo."
    +                , "boo.js.boo" ]
    +      }
    +    , ["*.!(js)", ["foo.bar", "foo.", "boo.js.boo"] ]
    +
    +    ].forEach(function (c) {
    +      if (typeof c === "function") return c()
    +      if (typeof c === "string") return t.comment(c)
    +
    +      var pattern = c[0]
    +        , expect = c[1].sort(alpha)
    +        , options = c[2]
    +        , f = c[3] || files
    +        , tapOpts = c[4] || {}
    +
    +      // options.debug = true
    +      var Class = mm.defaults(options).Minimatch
    +      var m = new Class(pattern, {})
    +      var r = m.makeRe()
    +      tapOpts.re = String(r) || JSON.stringify(r)
    +      tapOpts.files = JSON.stringify(f)
    +      tapOpts.pattern = pattern
    +      tapOpts.set = m.set
    +      tapOpts.negated = m.negate
    +
    +      var actual = mm.match(f, pattern, options)
    +      actual.sort(alpha)
    +
    +      t.equivalent( actual, expect
    +                  , JSON.stringify(pattern) + " " + JSON.stringify(expect)
    +                  , tapOpts )
    +    })
    +
    +  t.comment("time=" + (Date.now() - start) + "ms")
    +  t.end()
    +})
    +
    +tap.test("global leak test", function (t) {
    +  var globalAfter = Object.keys(global)
    +  t.equivalent(globalAfter, globalBefore, "no new globals, please")
    +  t.end()
    +})
    +
    +function alpha (a, b) {
    +  return a > b ? 1 : -1
    +}
    diff --git a/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
    new file mode 100644
    index 0000000..6676e26
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js
    @@ -0,0 +1,8 @@
    +var test = require('tap').test
    +var minimatch = require('../')
    +
    +test('extglob ending with statechar', function(t) {
    +  t.notOk(minimatch('ax', 'a?(b*)'))
    +  t.ok(minimatch('ax', '?(a*|b)'))
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/package.json b/node_modules/mocha/node_modules/glob/package.json
    new file mode 100644
    index 0000000..97022f1
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/package.json
    @@ -0,0 +1,58 @@
    +{
    +  "author": {
    +    "name": "Isaac Z. Schlueter",
    +    "email": "i@izs.me",
    +    "url": "http://blog.izs.me/"
    +  },
    +  "name": "glob",
    +  "description": "a little globber",
    +  "version": "3.2.11",
    +  "repository": {
    +    "type": "git",
    +    "url": "git://github.com/isaacs/node-glob.git"
    +  },
    +  "main": "glob.js",
    +  "engines": {
    +    "node": "*"
    +  },
    +  "dependencies": {
    +    "inherits": "2",
    +    "minimatch": "0.3"
    +  },
    +  "devDependencies": {
    +    "tap": "~0.4.0",
    +    "mkdirp": "0",
    +    "rimraf": "1"
    +  },
    +  "scripts": {
    +    "test": "tap test/*.js",
    +    "test-regen": "TEST_REGEN=1 node test/00-setup.js"
    +  },
    +  "license": "BSD",
    +  "gitHead": "73f57e99510582b2024b762305970ebcf9b70aa2",
    +  "bugs": {
    +    "url": "https://github.com/isaacs/node-glob/issues"
    +  },
    +  "homepage": "https://github.com/isaacs/node-glob",
    +  "_id": "glob@3.2.11",
    +  "_shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d",
    +  "_from": "glob@3.2.11",
    +  "_npmVersion": "1.4.10",
    +  "_npmUser": {
    +    "name": "isaacs",
    +    "email": "i@izs.me"
    +  },
    +  "maintainers": [
    +    {
    +      "name": "isaacs",
    +      "email": "i@izs.me"
    +    }
    +  ],
    +  "dist": {
    +    "shasum": "4a973f635b9190f715d10987d5c00fd2815ebe3d",
    +    "tarball": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz"
    +  },
    +  "directories": {},
    +  "_resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/glob/test/00-setup.js b/node_modules/mocha/node_modules/glob/test/00-setup.js
    new file mode 100644
    index 0000000..245afaf
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/00-setup.js
    @@ -0,0 +1,176 @@
    +// just a little pre-run script to set up the fixtures.
    +// zz-finish cleans it up
    +
    +var mkdirp = require("mkdirp")
    +var path = require("path")
    +var i = 0
    +var tap = require("tap")
    +var fs = require("fs")
    +var rimraf = require("rimraf")
    +
    +var files =
    +[ "a/.abcdef/x/y/z/a"
    +, "a/abcdef/g/h"
    +, "a/abcfed/g/h"
    +, "a/b/c/d"
    +, "a/bc/e/f"
    +, "a/c/d/c/b"
    +, "a/cb/e/f"
    +]
    +
    +var symlinkTo = path.resolve(__dirname, "a/symlink/a/b/c")
    +var symlinkFrom = "../.."
    +
    +files = files.map(function (f) {
    +  return path.resolve(__dirname, f)
    +})
    +
    +tap.test("remove fixtures", function (t) {
    +  rimraf(path.resolve(__dirname, "a"), function (er) {
    +    t.ifError(er, "remove fixtures")
    +    t.end()
    +  })
    +})
    +
    +files.forEach(function (f) {
    +  tap.test(f, function (t) {
    +    var d = path.dirname(f)
    +    mkdirp(d, 0755, function (er) {
    +      if (er) {
    +        t.fail(er)
    +        return t.bailout()
    +      }
    +      fs.writeFile(f, "i like tests", function (er) {
    +        t.ifError(er, "make file")
    +        t.end()
    +      })
    +    })
    +  })
    +})
    +
    +if (process.platform !== "win32") {
    +  tap.test("symlinky", function (t) {
    +    var d = path.dirname(symlinkTo)
    +    console.error("mkdirp", d)
    +    mkdirp(d, 0755, function (er) {
    +      t.ifError(er)
    +      fs.symlink(symlinkFrom, symlinkTo, "dir", function (er) {
    +        t.ifError(er, "make symlink")
    +        t.end()
    +      })
    +    })
    +  })
    +}
    +
    +;["foo","bar","baz","asdf","quux","qwer","rewq"].forEach(function (w) {
    +  w = "/tmp/glob-test/" + w
    +  tap.test("create " + w, function (t) {
    +    mkdirp(w, function (er) {
    +      if (er)
    +        throw er
    +      t.pass(w)
    +      t.end()
    +    })
    +  })
    +})
    +
    +
    +// generate the bash pattern test-fixtures if possible
    +if (process.platform === "win32" || !process.env.TEST_REGEN) {
    +  console.error("Windows, or TEST_REGEN unset.  Using cached fixtures.")
    +  return
    +}
    +
    +var spawn = require("child_process").spawn;
    +var globs =
    +  // put more patterns here.
    +  // anything that would be directly in / should be in /tmp/glob-test
    +  ["test/a/*/+(c|g)/./d"
    +  ,"test/a/**/[cg]/../[cg]"
    +  ,"test/a/{b,c,d,e,f}/**/g"
    +  ,"test/a/b/**"
    +  ,"test/**/g"
    +  ,"test/a/abc{fed,def}/g/h"
    +  ,"test/a/abc{fed/g,def}/**/"
    +  ,"test/a/abc{fed/g,def}/**///**/"
    +  ,"test/**/a/**/"
    +  ,"test/+(a|b|c)/a{/,bc*}/**"
    +  ,"test/*/*/*/f"
    +  ,"test/**/f"
    +  ,"test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**"
    +  ,"{./*/*,/tmp/glob-test/*}"
    +  ,"{/tmp/glob-test/*,*}" // evil owl face!  how you taunt me!
    +  ,"test/a/!(symlink)/**"
    +  ]
    +var bashOutput = {}
    +var fs = require("fs")
    +
    +globs.forEach(function (pattern) {
    +  tap.test("generate fixture " + pattern, function (t) {
    +    var cmd = "shopt -s globstar && " +
    +              "shopt -s extglob && " +
    +              "shopt -s nullglob && " +
    +              // "shopt >&2; " +
    +              "eval \'for i in " + pattern + "; do echo $i; done\'"
    +    var cp = spawn("bash", ["-c", cmd], { cwd: path.dirname(__dirname) })
    +    var out = []
    +    cp.stdout.on("data", function (c) {
    +      out.push(c)
    +    })
    +    cp.stderr.pipe(process.stderr)
    +    cp.on("close", function (code) {
    +      out = flatten(out)
    +      if (!out)
    +        out = []
    +      else
    +        out = cleanResults(out.split(/\r*\n/))
    +
    +      bashOutput[pattern] = out
    +      t.notOk(code, "bash test should finish nicely")
    +      t.end()
    +    })
    +  })
    +})
    +
    +tap.test("save fixtures", function (t) {
    +  var fname = path.resolve(__dirname, "bash-results.json")
    +  var data = JSON.stringify(bashOutput, null, 2) + "\n"
    +  fs.writeFile(fname, data, function (er) {
    +    t.ifError(er)
    +    t.end()
    +  })
    +})
    +
    +function cleanResults (m) {
    +  // normalize discrepancies in ordering, duplication,
    +  // and ending slashes.
    +  return m.map(function (m) {
    +    return m.replace(/\/+/g, "/").replace(/\/$/, "")
    +  }).sort(alphasort).reduce(function (set, f) {
    +    if (f !== set[set.length - 1]) set.push(f)
    +    return set
    +  }, []).sort(alphasort).map(function (f) {
    +    // de-windows
    +    return (process.platform !== 'win32') ? f
    +           : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
    +  })
    +}
    +
    +function flatten (chunks) {
    +  var s = 0
    +  chunks.forEach(function (c) { s += c.length })
    +  var out = new Buffer(s)
    +  s = 0
    +  chunks.forEach(function (c) {
    +    c.copy(out, s)
    +    s += c.length
    +  })
    +
    +  return out.toString().trim()
    +}
    +
    +function alphasort (a, b) {
    +  a = a.toLowerCase()
    +  b = b.toLowerCase()
    +  return a > b ? 1 : a < b ? -1 : 0
    +}
    diff --git a/node_modules/mocha/node_modules/glob/test/bash-comparison.js b/node_modules/mocha/node_modules/glob/test/bash-comparison.js
    new file mode 100644
    index 0000000..239ed1a
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/bash-comparison.js
    @@ -0,0 +1,63 @@
    +// basic test
    +// show that it does the same thing by default as the shell.
    +var tap = require("tap")
    +, child_process = require("child_process")
    +, bashResults = require("./bash-results.json")
    +, globs = Object.keys(bashResults)
    +, glob = require("../")
    +, path = require("path")
    +
    +// run from the root of the project
    +// this is usually where you're at anyway, but be sure.
    +process.chdir(path.resolve(__dirname, ".."))
    +
    +function alphasort (a, b) {
    +  a = a.toLowerCase()
    +  b = b.toLowerCase()
    +  return a > b ? 1 : a < b ? -1 : 0
    +}
    +
    +globs.forEach(function (pattern) {
    +  var expect = bashResults[pattern]
    +  // anything regarding the symlink thing will fail on windows, so just skip it
    +  if (process.platform === "win32" &&
    +      expect.some(function (m) {
    +        return /\/symlink\//.test(m)
    +      }))
    +    return
    +
    +  tap.test(pattern, function (t) {
    +    glob(pattern, function (er, matches) {
    +      if (er)
    +        throw er
    +
    +      // sort and unmark, just to match the shell results
    +      matches = cleanResults(matches)
    +
    +      t.deepEqual(matches, expect, pattern)
    +      t.end()
    +    })
    +  })
    +
    +  tap.test(pattern + " sync", function (t) {
    +    var matches = cleanResults(glob.sync(pattern))
    +
    +    t.deepEqual(matches, expect, "should match shell")
    +    t.end()
    +  })
    +})
    +
    +function cleanResults (m) {
    +  // normalize discrepancies in ordering, duplication,
    +  // and ending slashes.
    +  return m.map(function (m) {
    +    return m.replace(/\/+/g, "/").replace(/\/$/, "")
    +  }).sort(alphasort).reduce(function (set, f) {
    +    if (f !== set[set.length - 1]) set.push(f)
    +    return set
    +  }, []).sort(alphasort).map(function (f) {
    +    // de-windows
    +    return (process.platform !== 'win32') ? f
    +           : f.replace(/^[a-zA-Z]:[\/\\]+/, '/').replace(/[\\\/]+/g, '/')
    +  })
    +}
    diff --git a/node_modules/mocha/node_modules/glob/test/bash-results.json b/node_modules/mocha/node_modules/glob/test/bash-results.json
    new file mode 100644
    index 0000000..8051c72
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/bash-results.json
    @@ -0,0 +1,351 @@
    +{
    +  "test/a/*/+(c|g)/./d": [
    +    "test/a/b/c/./d"
    +  ],
    +  "test/a/**/[cg]/../[cg]": [
    +    "test/a/abcdef/g/../g",
    +    "test/a/abcfed/g/../g",
    +    "test/a/b/c/../c",
    +    "test/a/c/../c",
    +    "test/a/c/d/c/../c",
    +    "test/a/symlink/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/../c"
    +  ],
    +  "test/a/{b,c,d,e,f}/**/g": [],
    +  "test/a/b/**": [
    +    "test/a/b",
    +    "test/a/b/c",
    +    "test/a/b/c/d"
    +  ],
    +  "test/**/g": [
    +    "test/a/abcdef/g",
    +    "test/a/abcfed/g"
    +  ],
    +  "test/a/abc{fed,def}/g/h": [
    +    "test/a/abcdef/g/h",
    +    "test/a/abcfed/g/h"
    +  ],
    +  "test/a/abc{fed/g,def}/**/": [
    +    "test/a/abcdef",
    +    "test/a/abcdef/g",
    +    "test/a/abcfed/g"
    +  ],
    +  "test/a/abc{fed/g,def}/**///**/": [
    +    "test/a/abcdef",
    +    "test/a/abcdef/g",
    +    "test/a/abcfed/g"
    +  ],
    +  "test/**/a/**/": [
    +    "test/a",
    +    "test/a/abcdef",
    +    "test/a/abcdef/g",
    +    "test/a/abcfed",
    +    "test/a/abcfed/g",
    +    "test/a/b",
    +    "test/a/b/c",
    +    "test/a/bc",
    +    "test/a/bc/e",
    +    "test/a/c",
    +    "test/a/c/d",
    +    "test/a/c/d/c",
    +    "test/a/cb",
    +    "test/a/cb/e",
    +    "test/a/symlink",
    +    "test/a/symlink/a",
    +    "test/a/symlink/a/b",
    +    "test/a/symlink/a/b/c",
    +    "test/a/symlink/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b"
    +  ],
    +  "test/+(a|b|c)/a{/,bc*}/**": [
    +    "test/a/abcdef",
    +    "test/a/abcdef/g",
    +    "test/a/abcdef/g/h",
    +    "test/a/abcfed",
    +    "test/a/abcfed/g",
    +    "test/a/abcfed/g/h"
    +  ],
    +  "test/*/*/*/f": [
    +    "test/a/bc/e/f",
    +    "test/a/cb/e/f"
    +  ],
    +  "test/**/f": [
    +    "test/a/bc/e/f",
    +    "test/a/cb/e/f"
    +  ],
    +  "test/a/symlink/a/b/c/a/b/c/a/b/c//a/b/c////a/b/c/**/b/c/**": [
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b",
    +    "test/a/symlink/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c/a/b/c"
    +  ],
    +  "{./*/*,/tmp/glob-test/*}": [
    +    "./examples/g.js",
    +    "./examples/usr-local.js",
    +    "./node_modules/inherits",
    +    "./node_modules/minimatch",
    +    "./node_modules/mkdirp",
    +    "./node_modules/rimraf",
    +    "./node_modules/tap",
    +    "./test/00-setup.js",
    +    "./test/a",
    +    "./test/bash-comparison.js",
    +    "./test/bash-results.json",
    +    "./test/cwd-test.js",
    +    "./test/globstar-match.js",
    +    "./test/mark.js",
    +    "./test/new-glob-optional-options.js",
    +    "./test/nocase-nomagic.js",
    +    "./test/pause-resume.js",
    +    "./test/readme-issue.js",
    +    "./test/root-nomount.js",
    +    "./test/root.js",
    +    "./test/stat.js",
    +    "./test/zz-cleanup.js",
    +    "/tmp/glob-test/asdf",
    +    "/tmp/glob-test/bar",
    +    "/tmp/glob-test/baz",
    +    "/tmp/glob-test/foo",
    +    "/tmp/glob-test/quux",
    +    "/tmp/glob-test/qwer",
    +    "/tmp/glob-test/rewq"
    +  ],
    +  "{/tmp/glob-test/*,*}": [
    +    "/tmp/glob-test/asdf",
    +    "/tmp/glob-test/bar",
    +    "/tmp/glob-test/baz",
    +    "/tmp/glob-test/foo",
    +    "/tmp/glob-test/quux",
    +    "/tmp/glob-test/qwer",
    +    "/tmp/glob-test/rewq",
    +    "examples",
    +    "glob.js",
    +    "LICENSE",
    +    "node_modules",
    +    "package.json",
    +    "README.md",
    +    "test"
    +  ],
    +  "test/a/!(symlink)/**": [
    +    "test/a/abcdef",
    +    "test/a/abcdef/g",
    +    "test/a/abcdef/g/h",
    +    "test/a/abcfed",
    +    "test/a/abcfed/g",
    +    "test/a/abcfed/g/h",
    +    "test/a/b",
    +    "test/a/b/c",
    +    "test/a/b/c/d",
    +    "test/a/bc",
    +    "test/a/bc/e",
    +    "test/a/bc/e/f",
    +    "test/a/c",
    +    "test/a/c/d",
    +    "test/a/c/d/c",
    +    "test/a/c/d/c/b",
    +    "test/a/cb",
    +    "test/a/cb/e",
    +    "test/a/cb/e/f"
    +  ]
    +}
    diff --git a/node_modules/mocha/node_modules/glob/test/cwd-test.js b/node_modules/mocha/node_modules/glob/test/cwd-test.js
    new file mode 100644
    index 0000000..352c27e
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/cwd-test.js
    @@ -0,0 +1,55 @@
    +var tap = require("tap")
    +
    +var origCwd = process.cwd()
    +process.chdir(__dirname)
    +
    +tap.test("changing cwd and searching for **/d", function (t) {
    +  var glob = require('../')
    +  var path = require('path')
    +  t.test('.', function (t) {
    +    glob('**/d', function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('a', function (t) {
    +    glob('**/d', {cwd:path.resolve('a')}, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ 'b/c/d', 'c/d' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('a/b', function (t) {
    +    glob('**/d', {cwd:path.resolve('a/b')}, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ 'c/d' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('a/b/', function (t) {
    +    glob('**/d', {cwd:path.resolve('a/b/')}, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ 'c/d' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('.', function (t) {
    +    glob('**/d', {cwd: process.cwd()}, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ 'a/b/c/d', 'a/c/d' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('cd -', function (t) {
    +    process.chdir(origCwd)
    +    t.end()
    +  })
    +
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/globstar-match.js b/node_modules/mocha/node_modules/glob/test/globstar-match.js
    new file mode 100644
    index 0000000..9b234fa
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/globstar-match.js
    @@ -0,0 +1,19 @@
    +var Glob = require("../glob.js").Glob
    +var test = require('tap').test
    +
    +test('globstar should not have dupe matches', function(t) {
    +  var pattern = 'a/**/[gh]'
    +  var g = new Glob(pattern, { cwd: __dirname })
    +  var matches = []
    +  g.on('match', function(m) {
    +    console.error('match %j', m)
    +    matches.push(m)
    +  })
    +  g.on('end', function(set) {
    +    console.error('set', set)
    +    matches = matches.sort()
    +    set = set.sort()
    +    t.same(matches, set, 'should have same set of matches')
    +    t.end()
    +  })
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/mark.js b/node_modules/mocha/node_modules/glob/test/mark.js
    new file mode 100644
    index 0000000..bf411c0
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/mark.js
    @@ -0,0 +1,118 @@
    +var test = require("tap").test
    +var glob = require('../')
    +process.chdir(__dirname)
    +
    +// expose timing issues
    +var lag = 5
    +glob.Glob.prototype._stat = function(o) { return function(f, cb) {
    +  var args = arguments
    +  setTimeout(function() {
    +    o.call(this, f, cb)
    +  }.bind(this), lag += 5)
    +}}(glob.Glob.prototype._stat)
    +
    +
    +test("mark, with **", function (t) {
    +  glob("a/*b*/**", {mark: true}, function (er, results) {
    +    if (er)
    +      throw er
    +    var expect =
    +      [ 'a/abcdef/',
    +        'a/abcdef/g/',
    +        'a/abcdef/g/h',
    +        'a/abcfed/',
    +        'a/abcfed/g/',
    +        'a/abcfed/g/h',
    +        'a/b/',
    +        'a/b/c/',
    +        'a/b/c/d',
    +        'a/bc/',
    +        'a/bc/e/',
    +        'a/bc/e/f',
    +        'a/cb/',
    +        'a/cb/e/',
    +        'a/cb/e/f' ]
    +
    +    t.same(results, expect)
    +    t.end()
    +  })
    +})
    +
    +test("mark, no / on pattern", function (t) {
    +  glob("a/*", {mark: true}, function (er, results) {
    +    if (er)
    +      throw er
    +    var expect = [ 'a/abcdef/',
    +                   'a/abcfed/',
    +                   'a/b/',
    +                   'a/bc/',
    +                   'a/c/',
    +                   'a/cb/' ]
    +
    +    if (process.platform !== "win32")
    +      expect.push('a/symlink/')
    +
    +    t.same(results, expect)
    +    t.end()
    +  }).on('match', function(m) {
    +    t.similar(m, /\/$/)
    +  })
    +})
    +
    +test("mark=false, no / on pattern", function (t) {
    +  glob("a/*", function (er, results) {
    +    if (er)
    +      throw er
    +    var expect = [ 'a/abcdef',
    +                   'a/abcfed',
    +                   'a/b',
    +                   'a/bc',
    +                   'a/c',
    +                   'a/cb' ]
    +
    +    if (process.platform !== "win32")
    +      expect.push('a/symlink')
    +    t.same(results, expect)
    +    t.end()
    +  }).on('match', function(m) {
    +    t.similar(m, /[^\/]$/)
    +  })
    +})
    +
    +test("mark=true, / on pattern", function (t) {
    +  glob("a/*/", {mark: true}, function (er, results) {
    +    if (er)
    +      throw er
    +    var expect = [ 'a/abcdef/',
    +                    'a/abcfed/',
    +                    'a/b/',
    +                    'a/bc/',
    +                    'a/c/',
    +                    'a/cb/' ]
    +    if (process.platform !== "win32")
    +      expect.push('a/symlink/')
    +    t.same(results, expect)
    +    t.end()
    +  }).on('match', function(m) {
    +    t.similar(m, /\/$/)
    +  })
    +})
    +
    +test("mark=false, / on pattern", function (t) {
    +  glob("a/*/", function (er, results) {
    +    if (er)
    +      throw er
    +    var expect = [ 'a/abcdef/',
    +                   'a/abcfed/',
    +                   'a/b/',
    +                   'a/bc/',
    +                   'a/c/',
    +                   'a/cb/' ]
    +    if (process.platform !== "win32")
    +      expect.push('a/symlink/')
    +    t.same(results, expect)
    +    t.end()
    +  }).on('match', function(m) {
    +    t.similar(m, /\/$/)
    +  })
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/new-glob-optional-options.js b/node_modules/mocha/node_modules/glob/test/new-glob-optional-options.js
    new file mode 100644
    index 0000000..3e7dc5a
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/new-glob-optional-options.js
    @@ -0,0 +1,10 @@
    +var Glob = require('../glob.js').Glob;
    +var test = require('tap').test;
    +
    +test('new glob, with cb, and no options', function (t) {
    +  new Glob(__filename, function(er, results) {
    +    if (er) throw er;
    +    t.same(results, [__filename]);
    +    t.end();
    +  });
    +});
    diff --git a/node_modules/mocha/node_modules/glob/test/nocase-nomagic.js b/node_modules/mocha/node_modules/glob/test/nocase-nomagic.js
    new file mode 100644
    index 0000000..2503f23
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/nocase-nomagic.js
    @@ -0,0 +1,113 @@
    +var fs = require('fs');
    +var test = require('tap').test;
    +var glob = require('../');
    +
    +test('mock fs', function(t) {
    +  var stat = fs.stat
    +  var statSync = fs.statSync
    +  var readdir = fs.readdir
    +  var readdirSync = fs.readdirSync
    +
    +  function fakeStat(path) {
    +    var ret
    +    switch (path.toLowerCase()) {
    +      case '/tmp': case '/tmp/':
    +        ret = { isDirectory: function() { return true } }
    +        break
    +      case '/tmp/a':
    +        ret = { isDirectory: function() { return false } }
    +        break
    +    }
    +    return ret
    +  }
    +
    +  fs.stat = function(path, cb) {
    +    var f = fakeStat(path);
    +    if (f) {
    +      process.nextTick(function() {
    +        cb(null, f)
    +      })
    +    } else {
    +      stat.call(fs, path, cb)
    +    }
    +  }
    +
    +  fs.statSync = function(path) {
    +    return fakeStat(path) || statSync.call(fs, path)
    +  }
    +
    +  function fakeReaddir(path) {
    +    var ret
    +    switch (path.toLowerCase()) {
    +      case '/tmp': case '/tmp/':
    +        ret = [ 'a', 'A' ]
    +        break
    +      case '/':
    +        ret = ['tmp', 'tMp', 'tMP', 'TMP']
    +    }
    +    return ret
    +  }
    +
    +  fs.readdir = function(path, cb) {
    +    var f = fakeReaddir(path)
    +    if (f)
    +      process.nextTick(function() {
    +        cb(null, f)
    +      })
    +    else
    +      readdir.call(fs, path, cb)
    +  }
    +
    +  fs.readdirSync = function(path) {
    +    return fakeReaddir(path) || readdirSync.call(fs, path)
    +  }
    +
    +  t.pass('mocked')
    +  t.end()
    +})
    +
    +test('nocase, nomagic', function(t) {
    +  var n = 2
    +  var want = [ '/TMP/A',
    +               '/TMP/a',
    +               '/tMP/A',
    +               '/tMP/a',
    +               '/tMp/A',
    +               '/tMp/a',
    +               '/tmp/A',
    +               '/tmp/a' ]
    +  glob('/tmp/a', { nocase: true }, function(er, res) {
    +    if (er)
    +      throw er
    +    t.same(res.sort(), want)
    +    if (--n === 0) t.end()
    +  })
    +  glob('/tmp/A', { nocase: true }, function(er, res) {
    +    if (er)
    +      throw er
    +    t.same(res.sort(), want)
    +    if (--n === 0) t.end()
    +  })
    +})
    +
    +test('nocase, with some magic', function(t) {
    +  t.plan(2)
    +  var want = [ '/TMP/A',
    +               '/TMP/a',
    +               '/tMP/A',
    +               '/tMP/a',
    +               '/tMp/A',
    +               '/tMp/a',
    +               '/tmp/A',
    +               '/tmp/a' ]
    +  glob('/tmp/*', { nocase: true }, function(er, res) {
    +    if (er)
    +      throw er
    +    t.same(res.sort(), want)
    +  })
    +  glob('/tmp/*', { nocase: true }, function(er, res) {
    +    if (er)
    +      throw er
    +    t.same(res.sort(), want)
    +  })
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/pause-resume.js b/node_modules/mocha/node_modules/glob/test/pause-resume.js
    new file mode 100644
    index 0000000..e1ffbab
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/pause-resume.js
    @@ -0,0 +1,73 @@
    +// show that no match events happen while paused.
    +var tap = require("tap")
    +, child_process = require("child_process")
    +// just some gnarly pattern with lots of matches
    +, pattern = "test/a/!(symlink)/**"
    +, bashResults = require("./bash-results.json")
    +, patterns = Object.keys(bashResults)
    +, glob = require("../")
    +, Glob = glob.Glob
    +, path = require("path")
    +
    +// run from the root of the project
    +// this is usually where you're at anyway, but be sure.
    +process.chdir(path.resolve(__dirname, ".."))
    +
    +function alphasort (a, b) {
    +  a = a.toLowerCase()
    +  b = b.toLowerCase()
    +  return a > b ? 1 : a < b ? -1 : 0
    +}
    +
    +function cleanResults (m) {
    +  // normalize discrepancies in ordering, duplication,
    +  // and ending slashes.
    +  return m.map(function (m) {
    +    return m.replace(/\/+/g, "/").replace(/\/$/, "")
    +  }).sort(alphasort).reduce(function (set, f) {
    +    if (f !== set[set.length - 1]) set.push(f)
    +    return set
    +  }, []).sort(alphasort).map(function (f) {
    +    // de-windows
    +    return (process.platform !== 'win32') ? f
    +           : f.replace(/^[a-zA-Z]:\\\\/, '/').replace(/\\/g, '/')
    +  })
    +}
    +
    +var globResults = []
    +tap.test("use a Glob object, and pause/resume it", function (t) {
    +  var g = new Glob(pattern)
    +  , paused = false
    +  , res = []
    +  , expect = bashResults[pattern]
    +
    +  g.on("pause", function () {
    +    console.error("pause")
    +  })
    +
    +  g.on("resume", function () {
    +    console.error("resume")
    +  })
    +
    +  g.on("match", function (m) {
    +    t.notOk(g.paused, "must not be paused")
    +    globResults.push(m)
    +    g.pause()
    +    t.ok(g.paused, "must be paused")
    +    setTimeout(g.resume.bind(g), 10)
    +  })
    +
    +  g.on("end", function (matches) {
    +    t.pass("reached glob end")
    +    globResults = cleanResults(globResults)
    +    matches = cleanResults(matches)
    +    t.deepEqual(matches, globResults,
    +      "end event matches should be the same as match events")
    +
    +    t.deepEqual(matches, expect,
    +      "glob matches should be the same as bash results")
    +
    +    t.end()
    +  })
    +})
    +
    diff --git a/node_modules/mocha/node_modules/glob/test/readme-issue.js b/node_modules/mocha/node_modules/glob/test/readme-issue.js
    new file mode 100644
    index 0000000..0b4e0be
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/readme-issue.js
    @@ -0,0 +1,36 @@
    +var test = require("tap").test
    +var glob = require("../")
    +
    +var mkdirp = require("mkdirp")
    +var fs = require("fs")
    +var rimraf = require("rimraf")
    +var dir = __dirname + "/package"
    +
    +test("setup", function (t) {
    +  mkdirp.sync(dir)
    +  fs.writeFileSync(dir + "/package.json", "{}", "ascii")
    +  fs.writeFileSync(dir + "/README", "x", "ascii")
    +  t.pass("setup done")
    +  t.end()
    +})
    +
    +test("glob", function (t) {
    +  var opt = {
    +    cwd: dir,
    +    nocase: true,
    +    mark: true
    +  }
    +
    +  glob("README?(.*)", opt, function (er, files) {
    +    if (er)
    +      throw er
    +    t.same(files, ["README"])
    +    t.end()
    +  })
    +})
    +
    +test("cleanup", function (t) {
    +  rimraf.sync(dir)
    +  t.pass("clean")
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/root-nomount.js b/node_modules/mocha/node_modules/glob/test/root-nomount.js
    new file mode 100644
    index 0000000..3ac5979
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/root-nomount.js
    @@ -0,0 +1,39 @@
    +var tap = require("tap")
    +
    +var origCwd = process.cwd()
    +process.chdir(__dirname)
    +
    +tap.test("changing root and searching for /b*/**", function (t) {
    +  var glob = require('../')
    +  var path = require('path')
    +  t.test('.', function (t) {
    +    glob('/b*/**', { globDebug: true, root: '.', nomount: true }, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('a', function (t) {
    +    glob('/b*/**', { globDebug: true, root: path.resolve('a'), nomount: true }, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('root=a, cwd=a/b', function (t) {
    +    glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b'), nomount: true }, function (er, matches) {
    +      t.ifError(er)
    +      t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ])
    +      t.end()
    +    })
    +  })
    +
    +  t.test('cd -', function (t) {
    +    process.chdir(origCwd)
    +    t.end()
    +  })
    +
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/root.js b/node_modules/mocha/node_modules/glob/test/root.js
    new file mode 100644
    index 0000000..95c23f9
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/root.js
    @@ -0,0 +1,46 @@
    +var t = require("tap")
    +
    +var origCwd = process.cwd()
    +process.chdir(__dirname)
    +
    +var glob = require('../')
    +var path = require('path')
    +
    +t.test('.', function (t) {
    +  glob('/b*/**', { globDebug: true, root: '.' }, function (er, matches) {
    +    t.ifError(er)
    +    t.like(matches, [])
    +    t.end()
    +  })
    +})
    +
    +
    +t.test('a', function (t) {
    +  console.error("root=" + path.resolve('a'))
    +  glob('/b*/**', { globDebug: true, root: path.resolve('a') }, function (er, matches) {
    +    t.ifError(er)
    +    var wanted = [
    +        '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f'
    +      ].map(function (m) {
    +        return path.join(path.resolve('a'), m).replace(/\\/g, '/')
    +      })
    +
    +    t.like(matches, wanted)
    +    t.end()
    +  })
    +})
    +
    +t.test('root=a, cwd=a/b', function (t) {
    +  glob('/b*/**', { globDebug: true, root: 'a', cwd: path.resolve('a/b') }, function (er, matches) {
    +    t.ifError(er)
    +    t.like(matches, [ '/b', '/b/c', '/b/c/d', '/bc', '/bc/e', '/bc/e/f' ].map(function (m) {
    +      return path.join(path.resolve('a'), m).replace(/\\/g, '/')
    +    }))
    +    t.end()
    +  })
    +})
    +
    +t.test('cd -', function (t) {
    +  process.chdir(origCwd)
    +  t.end()
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/stat.js b/node_modules/mocha/node_modules/glob/test/stat.js
    new file mode 100644
    index 0000000..6291711
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/stat.js
    @@ -0,0 +1,32 @@
    +var glob = require('../')
    +var test = require('tap').test
    +var path = require('path')
    +
    +test('stat all the things', function(t) {
    +  var g = new glob.Glob('a/*abc*/**', { stat: true, cwd: __dirname })
    +  var matches = []
    +  g.on('match', function(m) {
    +    matches.push(m)
    +  })
    +  var stats = []
    +  g.on('stat', function(m) {
    +    stats.push(m)
    +  })
    +  g.on('end', function(eof) {
    +    stats = stats.sort()
    +    matches = matches.sort()
    +    eof = eof.sort()
    +    t.same(stats, matches)
    +    t.same(eof, matches)
    +    var cache = Object.keys(this.statCache)
    +    t.same(cache.map(function (f) {
    +      return path.relative(__dirname, f)
    +    }).sort(), matches)
    +
    +    cache.forEach(function(c) {
    +      t.equal(typeof this.statCache[c], 'object')
    +    }, this)
    +
    +    t.end()
    +  })
    +})
    diff --git a/node_modules/mocha/node_modules/glob/test/zz-cleanup.js b/node_modules/mocha/node_modules/glob/test/zz-cleanup.js
    new file mode 100644
    index 0000000..e085f0f
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/glob/test/zz-cleanup.js
    @@ -0,0 +1,11 @@
    +// remove the fixtures
    +var tap = require("tap")
    +, rimraf = require("rimraf")
    +, path = require("path")
    +
    +tap.test("cleanup fixtures", function (t) {
    +  rimraf(path.resolve(__dirname, "a"), function (er) {
    +    t.ifError(er, "removed")
    +    t.end()
    +  })
    +})
    diff --git a/node_modules/mocha/node_modules/growl/History.md b/node_modules/mocha/node_modules/growl/History.md
    new file mode 100644
    index 0000000..a4b7b49
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/growl/History.md
    @@ -0,0 +1,63 @@
    +
    +1.7.0 / 2012-12-30 
    +==================
    +
    +  * support transient notifications in Gnome
    +
    +1.6.1 / 2012-09-25 
    +==================
    +
    +  * restore compatibility with node < 0.8 [fgnass]
    +
    +1.6.0 / 2012-09-06 
    +==================
    +
    +  * add notification center support [drudge]
    +
    +1.5.1 / 2012-04-08 
    +==================
    +
    +  * Merge pull request #16 from KyleAMathews/patch-1
    +  * Fixes #15
    +
    +1.5.0 / 2012-02-08 
    +==================
    +
    +  * Added windows support [perfusorius]
    +
    +1.4.1 / 2011-12-28 
    +==================
    +
    +  * Fixed: dont exit(). Closes #9
    +
    +1.4.0 / 2011-12-17 
    +==================
    +
    +  * Changed API: `growl.notify()` -> `growl()`
    +
    +1.3.0 / 2011-12-17 
    +==================
    +
    +  * Added support for Ubuntu/Debian/Linux users [niftylettuce]
    +  * Fixed: send notifications even if title not specified [alessioalex]
    +
    +1.2.0 / 2011-10-06 
    +==================
    +
    +  * Add support for priority.
    +
    +1.1.0 / 2011-03-15 
    +==================
    +
    +  * Added optional callbacks
    +  * Added parsing of version
    +
    +1.0.1 / 2010-03-26
    +==================
    +
    +  * Fixed; sys.exec -> child_process.exec to support latest node
    +
    +1.0.0 / 2010-03-19
    +==================
    +  
    +  * Initial release
    diff --git a/node_modules/mocha/node_modules/growl/Readme.md b/node_modules/mocha/node_modules/growl/Readme.md
    new file mode 100644
    index 0000000..785344e
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/growl/Readme.md
    @@ -0,0 +1,108 @@
    +# Growl for nodejs
    +
    +Growl support for Nodejs. This is essentially a port of my [Ruby Growl Library](http://github.com/visionmedia/growl). Ubuntu/Linux support added thanks to [@niftylettuce](http://github.com/niftylettuce).
    +
    +## Installation
    +
    +### Install
    +
    +### Mac OS X (Darwin):
    +
    +  Install [growlnotify(1)](http://growl.info/extras.php#growlnotify). On OS X 10.8, Notification Center is supported using [terminal-notifier](https://github.com/alloy/terminal-notifier). To install:
    +
    +    $ sudo gem install terminal-notifier
    +
    +  Install [npm](http://npmjs.org/) and run:
    +
    +    $ npm install growl
    +
    +### Ubuntu (Linux):
    +
    +  Install `notify-send` through the [libnotify-bin](http://packages.ubuntu.com/libnotify-bin) package:
    +
    +    $ sudo apt-get install libnotify-bin
    +
    +  Install [npm](http://npmjs.org/) and run:
    +
    +    $ npm install growl
    +
    +### Windows:
    +
    +  Download and install [Growl for Windows](http://www.growlforwindows.com/gfw/default.aspx)
    +
    +  Download [growlnotify](http://www.growlforwindows.com/gfw/help/growlnotify.aspx) - **IMPORTANT :** Unpack growlnotify to a folder that is present in your path!
    +
    +  Install [npm](http://npmjs.org/) and run:
    +
    +    $ npm install growl
    +
    +## Examples
    +
    +Callback functions are optional
    +
    +```javascript
    +var growl = require('growl')
    +growl('You have mail!')
    +growl('5 new messages', { sticky: true })
    +growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true })
    +growl('Message with title', { title: 'Title'})
    +growl('Set priority', { priority: 2 })
    +growl('Show Safari icon', { image: 'Safari' })
    +growl('Show icon', { image: 'path/to/icon.icns' })
    +growl('Show image', { image: 'path/to/my.image.png' })
    +growl('Show png filesystem icon', { image: 'png' })
    +growl('Show pdf filesystem icon', { image: 'article.pdf' })
    +growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(err){
    +  // ... notified
    +})
    +```
    +
    +## Options
    +
    +  - title
    +    - notification title
    +  - name
    +    - application name
    +  - priority
    +    - priority for the notification (default is 0)
    +  - sticky
    +    - weither or not the notification should remainin until closed
    +  - image
    +    - Auto-detects the context:
    +      - 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
    +  - exec
    +    - manually specify a shell command instead
    +      - appends message to end of shell command
    +      - or, replaces `%s` with message
    +      - optionally prepends title (example: `title: message`)
    +      - examples: `{exec: 'tmux display-message'}`, `{exec: 'echo "%s" > messages.log}`
    +
    +## License
    +
    +(The MIT License)
    +
    +Copyright (c) 2009 TJ Holowaychuk 
    +Copyright (c) 2016 Joshua Boy Nicolai Appelman 
    +
    +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.
    diff --git a/node_modules/mocha/node_modules/growl/lib/growl.js b/node_modules/mocha/node_modules/growl/lib/growl.js
    new file mode 100644
    index 0000000..719b5af
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/growl/lib/growl.js
    @@ -0,0 +1,290 @@
    +// Growl - Copyright TJ Holowaychuk  (MIT Licensed)
    +
    +/**
    + * Module dependencies.
    + */
    +
    +var exec = require('child_process').exec
    +  , fs = require('fs')
    +  , path = require('path')
    +  , exists = fs.existsSync || path.existsSync
    +  , os = require('os')
    +  , quote = JSON.stringify
    +  , cmd;
    +
    +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;
    +  }
    +}
    +
    +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;
    +}
    +
    +/**
    + * Expose `growl`.
    + */
    +
    +exports = module.exports = growl;
    +
    +/**
    + * Node-growl version.
    + */
    +
    +exports.version = '1.4.1'
    +
    +/**
    + * 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
    + */
    +
    +function growl(msg, options, fn) {
    +  var image
    +    , args
    +    , options = options || {}
    +    , fn = fn || function(){};
    +
    +  if (options.exec) {
    +    cmd = {
    +        type: "Custom"
    +      , pkg: options.exec
    +      , range: []
    +    };
    +  }
    +
    +  // noop
    +  if (!cmd) return fn(new Error('growl not supported on this platform'));
    +  args = [cmd.pkg];
    +
    +  // 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;
    +    }
    +  }
    +
    +  // sticky
    +  if (options.sticky) args.push(cmd.sticky);
    +
    +  // 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);
    +    }
    +  }
    +
    +  //sound
    +  if(options.sound && cmd.type === 'Darwin-NotificationCenter'){
    +    args.push(cmd.sound, options.sound)
    +  }
    +
    +  // name
    +  if (options.name && cmd.type === "Darwin-Growl") {
    +    args.push('--name', options.name);
    +  }
    +
    +  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 '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;
    +    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;
    +  }
    +
    +  // execute
    +  exec(args.join(' '), fn);
    +};
    diff --git a/node_modules/mocha/node_modules/growl/package.json b/node_modules/mocha/node_modules/growl/package.json
    new file mode 100644
    index 0000000..a8d964a
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/growl/package.json
    @@ -0,0 +1,51 @@
    +{
    +  "name": "growl",
    +  "version": "1.9.2",
    +  "description": "Growl unobtrusive notifications",
    +  "author": {
    +    "name": "TJ Holowaychuk",
    +    "email": "tj@vision-media.ca"
    +  },
    +  "maintainers": [
    +    {
    +      "name": "tjholowaychuk",
    +      "email": "tj@vision-media.ca"
    +    },
    +    {
    +      "name": "jbnicolai",
    +      "email": "jappelman@xebia.com"
    +    }
    +  ],
    +  "repository": {
    +    "type": "git",
    +    "url": "git://github.com/tj/node-growl.git"
    +  },
    +  "main": "./lib/growl.js",
    +  "license": "MIT",
    +  "gitHead": "dc8aae046df328edd32dd69f3cd2d6b114d7018e",
    +  "bugs": {
    +    "url": "https://github.com/tj/node-growl/issues"
    +  },
    +  "homepage": "https://github.com/tj/node-growl",
    +  "_id": "growl@1.9.2",
    +  "scripts": {},
    +  "_shasum": "0ea7743715db8d8de2c5ede1775e1b45ac85c02f",
    +  "_from": "growl@1.9.2",
    +  "_npmVersion": "2.11.3",
    +  "_nodeVersion": "0.12.7",
    +  "_npmUser": {
    +    "name": "jbnicolai",
    +    "email": "jappelman@xebia.com"
    +  },
    +  "dist": {
    +    "shasum": "0ea7743715db8d8de2c5ede1775e1b45ac85c02f",
    +    "tarball": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz"
    +  },
    +  "_npmOperationalInternal": {
    +    "host": "packages-6-west.internal.npmjs.com",
    +    "tmp": "tmp/growl-1.9.2.tgz_1456056369289_0.9604133665561676"
    +  },
    +  "directories": {},
    +  "_resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
    +  "readme": "ERROR: No README data found!"
    +}
    diff --git a/node_modules/mocha/node_modules/growl/test.js b/node_modules/mocha/node_modules/growl/test.js
    new file mode 100644
    index 0000000..9bb09d9
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/growl/test.js
    @@ -0,0 +1,31 @@
    +
    +var growl = require('./lib/growl')
    +
    +growl('Support sound notifications', {title: 'Make a sound', sound: 'purr'});
    +growl('You have mail!')
    +growl('5 new messages', { sticky: true })
    +growl('5 new emails', { title: 'Email Client', image: 'Safari', sticky: true })
    +growl('Message with title', { title: 'Title'})
    +growl('Set priority', { priority: 2 })
    +growl('Show Safari icon', { image: 'Safari' })
    +growl('Show icon', { image: 'path/to/icon.icns' })
    +growl('Show image', { image: 'path/to/my.image.png' })
    +growl('Show png filesystem icon', { image: 'png' })
    +growl('Show pdf filesystem icon', { image: 'article.pdf' })
    +growl('Show pdf filesystem icon', { image: 'article.pdf' }, function(){
    +  console.log('callback');
    +})
    +growl('Show pdf filesystem icon', { title: 'Use show()', image: 'article.pdf' })
    +growl('here \' are \n some \\ characters that " need escaping', {}, function(error, stdout, stderr) {
    +  if (error !== null) throw new Error('escaping failed:\n' + stdout + stderr);
    +})
    +growl('Allow custom notifiers', { exec: 'echo XXX %s' }, function(error, stdout, stderr) {
    +  console.log(stdout);
    +})
    +growl('Allow custom notifiers', { title: 'test', exec: 'echo YYY' }, function(error, stdout, stderr) {
    +  console.log(stdout);
    +})
    +growl('Allow custom notifiers', { title: 'test', exec: 'echo ZZZ %s' }, function(error, stdout, stderr) {
    +  console.log(stdout);
    +})
    +growl('Open a URL', { url: 'https://npmjs.org/package/growl' });
    diff --git a/node_modules/mocha/node_modules/jade/.npmignore b/node_modules/mocha/node_modules/jade/.npmignore
    new file mode 100644
    index 0000000..b9af3d4
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/jade/.npmignore
    @@ -0,0 +1,15 @@
    +test
    +support
    +benchmarks
    +examples
    +lib-cov
    +coverage.html
    +.gitmodules
    +.travis.yml
    +History.md
    +Readme.md
    +Makefile
    +test/
    +support/
    +benchmarks/
    +examples/
    diff --git a/node_modules/mocha/node_modules/jade/LICENSE b/node_modules/mocha/node_modules/jade/LICENSE
    new file mode 100644
    index 0000000..8ad0e0d
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/jade/LICENSE
    @@ -0,0 +1,22 @@
    +(The MIT License)
    +
    +Copyright (c) 2009-2010 TJ Holowaychuk 
    +
    +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.
    \ No newline at end of file
    diff --git a/node_modules/mocha/node_modules/jade/bin/jade b/node_modules/mocha/node_modules/jade/bin/jade
    new file mode 100755
    index 0000000..7e6002f
    --- /dev/null
    +++ b/node_modules/mocha/node_modules/jade/bin/jade
    @@ -0,0 +1,147 @@
    +#!/usr/bin/env node
    +
    +/**
    + * Module dependencies.
    + */
    +
    +var fs = require('fs')
    +  , program = require('commander')
    +  , path = require('path')
    +  , basename = path.basename
    +  , dirname = path.dirname
    +  , resolve = path.resolve
    +  , join = path.join
    +  , mkdirp = require('mkdirp')
    +  , jade = require('../');
    +
    +// jade options
    +
    +var options = {};
    +
    +// options
    +
    +program
    +  .version(jade.version)
    +  .usage('[options] [dir|file ...]')
    +  .option('-o, --obj ', 'javascript options object')
    +  .option('-O, --out 
    ', 'output the compiled html to ') + .option('-p, --path ', 'filename used to resolve includes') + .option('-P, --pretty', 'compile pretty html output') + .option('-c, --client', 'compile for client-side runtime.js') + .option('-D, --no-debug', 'compile without debugging (smaller functions)') + +program.on('--help', function(){ + console.log(' Examples:'); + console.log(''); + console.log(' # translate jade the templates dir'); + console.log(' $ jade templates'); + console.log(''); + console.log(' # create {foo,bar}.html'); + console.log(' $ jade {foo,bar}.jade'); + console.log(''); + console.log(' # jade over stdio'); + console.log(' $ jade < my.jade > my.html'); + console.log(''); + console.log(' # jade over stdio'); + console.log(' $ echo "h1 Jade!" | jade'); + console.log(''); + console.log(' # foo, bar dirs rendering to /tmp'); + console.log(' $ jade foo bar --out /tmp '); + console.log(''); +}); + +program.parse(process.argv); + +// options given, parse them + +if (program.obj) options = eval('(' + program.obj + ')'); + +// --filename + +if (program.path) options.filename = program.path; + +// --no-debug + +options.compileDebug = program.debug; + +// --client + +options.client = program.client; + +// --pretty + +options.pretty = program.pretty; + +// left-over args are file paths + +var files = program.args; + +// compile files + +if (files.length) { + console.log(); + files.forEach(renderFile); + process.on('exit', console.log); +// stdio +} else { + stdin(); +} + +/** + * Compile from stdin. + */ + +function stdin() { + var buf = ''; + process.stdin.setEncoding('utf8'); + process.stdin.on('data', function(chunk){ buf += chunk; }); + process.stdin.on('end', function(){ + var fn = jade.compile(buf, options); + var output = options.client + ? fn.toString() + : fn(options); + process.stdout.write(output); + }).resume(); +} + +/** + * Process the given path, compiling the jade files found. + * Always walk the subdirectories. + */ + +function renderFile(path) { + var re = /\.jade$/; + fs.lstat(path, function(err, stat) { + if (err) throw err; + // Found jade file + if (stat.isFile() && re.test(path)) { + fs.readFile(path, 'utf8', function(err, str){ + if (err) throw err; + options.filename = path; + var fn = jade.compile(str, options); + var extname = options.client ? '.js' : '.html'; + path = path.replace(re, extname); + if (program.out) path = join(program.out, basename(path)); + var dir = resolve(dirname(path)); + mkdirp(dir, 0755, function(err){ + if (err) throw err; + var output = options.client + ? fn.toString() + : fn(options); + fs.writeFile(path, output, function(err){ + if (err) throw err; + console.log(' \033[90mrendered \033[36m%s\033[0m', path); + }); + }); + }); + // Found directory + } else if (stat.isDirectory()) { + fs.readdir(path, function(err, files) { + if (err) throw err; + files.map(function(filename) { + return path + '/' + filename; + }).forEach(renderFile); + }); + } + }); +} diff --git a/node_modules/mocha/node_modules/jade/index.js b/node_modules/mocha/node_modules/jade/index.js new file mode 100644 index 0000000..8ad059f --- /dev/null +++ b/node_modules/mocha/node_modules/jade/index.js @@ -0,0 +1,4 @@ + +module.exports = process.env.JADE_COV + ? require('./lib-cov/jade') + : require('./lib/jade'); \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/jade.js b/node_modules/mocha/node_modules/jade/jade.js new file mode 100644 index 0000000..1983a20 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/jade.js @@ -0,0 +1,3586 @@ +(function() { + +// CommonJS require() + +function require(p){ + var path = require.resolve(p) + , mod = require.modules[path]; + if (!mod) throw new Error('failed to require "' + p + '"'); + if (!mod.exports) { + mod.exports = {}; + mod.call(mod.exports, mod, mod.exports, require.relative(path)); + } + return mod.exports; + } + +require.modules = {}; + +require.resolve = function (path){ + var orig = path + , reg = path + '.js' + , index = path + '/index.js'; + return require.modules[reg] && reg + || require.modules[index] && index + || orig; + }; + +require.register = function (path, fn){ + require.modules[path] = fn; + }; + +require.relative = function (parent) { + return function(p){ + if ('.' != p.charAt(0)) return require(p); + + var path = parent.split('/') + , segs = p.split('/'); + path.pop(); + + for (var i = 0; i < segs.length; i++) { + var seg = segs[i]; + if ('..' == seg) path.pop(); + else if ('.' != seg) path.push(seg); + } + + return require(path.join('/')); + }; + }; + + +require.register("compiler.js", function(module, exports, require){ + +/*! + * Jade - Compiler + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var nodes = require('./nodes') + , filters = require('./filters') + , doctypes = require('./doctypes') + , selfClosing = require('./self-closing') + , runtime = require('./runtime') + , utils = require('./utils'); + + + if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } + } + + if (!String.prototype.trimLeft) { + String.prototype.trimLeft = function(){ + return this.replace(/^\s+/, ''); + } + } + + + +/** + * Initialize `Compiler` with the given `node`. + * + * @param {Node} node + * @param {Object} options + * @api public + */ + +var Compiler = module.exports = function Compiler(node, options) { + this.options = options = options || {}; + this.node = node; + this.hasCompiledDoctype = false; + this.hasCompiledTag = false; + this.pp = options.pretty || false; + this.debug = false !== options.compileDebug; + this.indents = 0; + this.parentIndents = 0; + if (options.doctype) this.setDoctype(options.doctype); +}; + +/** + * Compiler prototype. + */ + +Compiler.prototype = { + + /** + * Compile parse tree to JavaScript. + * + * @api public + */ + + compile: function(){ + this.buf = ['var interp;']; + if (this.pp) this.buf.push("var __indent = [];"); + this.lastBufferedIdx = -1; + this.visit(this.node); + return this.buf.join('\n'); + }, + + /** + * Sets the default doctype `name`. Sets terse mode to `true` when + * html 5 is used, causing self-closing tags to end with ">" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {string} name + * @api public + */ + + setDoctype: function(name){ + var doctype = doctypes[(name || 'default').toLowerCase()]; + doctype = doctype || ''; + this.doctype = doctype; + this.terse = '5' == name || 'html' == name; + this.xml = 0 == this.doctype.indexOf(' 1 && !escape && block.nodes[0].isText && block.nodes[1].isText) + this.prettyIndent(1, true); + + for (var i = 0; i < len; ++i) { + // Pretty print text + if (pp && i > 0 && !escape && block.nodes[i].isText && block.nodes[i-1].isText) + this.prettyIndent(1, false); + + this.visit(block.nodes[i]); + // Multiple text nodes are separated by newlines + if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText) + this.buffer('\\n'); + } + }, + + /** + * Visit `doctype`. Sets terse mode to `true` when html 5 + * is used, causing self-closing tags to end with ">" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {Doctype} doctype + * @api public + */ + + visitDoctype: function(doctype){ + if (doctype && (doctype.val || !this.doctype)) { + this.setDoctype(doctype.val || 'default'); + } + + if (this.doctype) this.buffer(this.doctype); + this.hasCompiledDoctype = true; + }, + + /** + * Visit `mixin`, generating a function that + * may be called within the template. + * + * @param {Mixin} mixin + * @api public + */ + + visitMixin: function(mixin){ + var name = mixin.name.replace(/-/g, '_') + '_mixin' + , args = mixin.args || '' + , block = mixin.block + , attrs = mixin.attrs + , pp = this.pp; + + if (mixin.call) { + if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join(' ') + "');") + if (block || attrs.length) { + + this.buf.push(name + '.call({'); + + if (block) { + this.buf.push('block: function(){'); + + // Render block with no indents, dynamically added when rendered + this.parentIndents++; + var _indents = this.indents; + this.indents = 0; + this.visit(mixin.block); + this.indents = _indents; + this.parentIndents--; + + if (attrs.length) { + this.buf.push('},'); + } else { + this.buf.push('}'); + } + } + + if (attrs.length) { + var val = this.attrs(attrs); + if (val.inherits) { + this.buf.push('attributes: merge({' + val.buf + + '}, attributes), escaped: merge(' + val.escaped + ', escaped, true)'); + } else { + this.buf.push('attributes: {' + val.buf + '}, escaped: ' + val.escaped); + } + } + + if (args) { + this.buf.push('}, ' + args + ');'); + } else { + this.buf.push('});'); + } + + } else { + this.buf.push(name + '(' + args + ');'); + } + if (pp) this.buf.push("__indent.pop();") + } else { + this.buf.push('var ' + name + ' = function(' + args + '){'); + this.buf.push('var block = this.block, attributes = this.attributes || {}, escaped = this.escaped || {};'); + this.parentIndents++; + this.visit(block); + this.parentIndents--; + this.buf.push('};'); + } + }, + + /** + * Visit `tag` buffering tag markup, generating + * attributes, visiting the `tag`'s code and block. + * + * @param {Tag} tag + * @api public + */ + + visitTag: function(tag){ + this.indents++; + var name = tag.name + , pp = this.pp; + + if (tag.buffer) name = "' + (" + name + ") + '"; + + if (!this.hasCompiledTag) { + if (!this.hasCompiledDoctype && 'html' == name) { + this.visitDoctype(); + } + this.hasCompiledTag = true; + } + + // pretty print + if (pp && !tag.isInline()) + this.prettyIndent(0, true); + + if ((~selfClosing.indexOf(name) || tag.selfClosing) && !this.xml) { + this.buffer('<' + name); + this.visitAttributes(tag.attrs); + this.terse + ? this.buffer('>') + : this.buffer('/>'); + } else { + // Optimize attributes buffering + if (tag.attrs.length) { + this.buffer('<' + name); + if (tag.attrs.length) this.visitAttributes(tag.attrs); + this.buffer('>'); + } else { + this.buffer('<' + name + '>'); + } + if (tag.code) this.visitCode(tag.code); + this.escape = 'pre' == tag.name; + this.visit(tag.block); + + // pretty print + if (pp && !tag.isInline() && 'pre' != tag.name && !tag.canInline()) + this.prettyIndent(0, true); + + this.buffer(''); + } + this.indents--; + }, + + /** + * Visit `filter`, throwing when the filter does not exist. + * + * @param {Filter} filter + * @api public + */ + + visitFilter: function(filter){ + var fn = filters[filter.name]; + + // unknown filter + if (!fn) { + if (filter.isASTFilter) { + throw new Error('unknown ast filter "' + filter.name + ':"'); + } else { + throw new Error('unknown filter ":' + filter.name + '"'); + } + } + + if (filter.isASTFilter) { + this.buf.push(fn(filter.block, this, filter.attrs)); + } else { + var text = filter.block.nodes.map(function(node){ return node.val }).join('\n'); + filter.attrs = filter.attrs || {}; + filter.attrs.filename = this.options.filename; + this.buffer(utils.text(fn(text, filter.attrs))); + } + }, + + /** + * Visit `text` node. + * + * @param {Text} text + * @api public + */ + + visitText: function(text){ + text = utils.text(text.val.replace(/\\/g, '\\\\')); + if (this.escape) text = escape(text); + this.buffer(text); + }, + + /** + * Visit a `comment`, only buffering when the buffer flag is set. + * + * @param {Comment} comment + * @api public + */ + + visitComment: function(comment){ + if (!comment.buffer) return; + if (this.pp) this.prettyIndent(1, true); + this.buffer(''); + }, + + /** + * Visit a `BlockComment`. + * + * @param {Comment} comment + * @api public + */ + + visitBlockComment: function(comment){ + if (!comment.buffer) return; + if (0 == comment.val.trim().indexOf('if')) { + this.buffer(''); + } else { + this.buffer(''); + } + }, + + /** + * Visit `code`, respecting buffer / escape flags. + * If the code is followed by a block, wrap it in + * a self-calling function. + * + * @param {Code} code + * @api public + */ + + visitCode: function(code){ + // Wrap code blocks with {}. + // we only wrap unbuffered code blocks ATM + // since they are usually flow control + + // Buffer code + if (code.buffer) { + var val = code.val.trimLeft(); + this.buf.push('var __val__ = ' + val); + val = 'null == __val__ ? "" : __val__'; + if (code.escape) val = 'escape(' + val + ')'; + this.buf.push("buf.push(" + val + ");"); + } else { + this.buf.push(code.val); + } + + // Block support + if (code.block) { + if (!code.buffer) this.buf.push('{'); + this.visit(code.block); + if (!code.buffer) this.buf.push('}'); + } + }, + + /** + * Visit `each` block. + * + * @param {Each} each + * @api public + */ + + visitEach: function(each){ + this.buf.push('' + + '// iterate ' + each.obj + '\n' + + ';(function(){\n' + + ' if (\'number\' == typeof ' + each.obj + '.length) {\n' + + ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n' + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + this.buf.push('' + + ' }\n' + + ' } else {\n' + + ' for (var ' + each.key + ' in ' + each.obj + ') {\n' + + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){' + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + this.buf.push(' }\n'); + + this.buf.push(' }\n }\n}).call(this);\n'); + }, + + /** + * Visit `attrs`. + * + * @param {Array} attrs + * @api public + */ + + visitAttributes: function(attrs){ + var val = this.attrs(attrs); + if (val.inherits) { + this.buf.push("buf.push(attrs(merge({ " + val.buf + + " }, attributes), merge(" + val.escaped + ", escaped, true)));"); + } else if (val.constant) { + eval('var buf={' + val.buf + '};'); + this.buffer(runtime.attrs(buf, JSON.parse(val.escaped)), true); + } else { + this.buf.push("buf.push(attrs({ " + val.buf + " }, " + val.escaped + "));"); + } + }, + + /** + * Compile attributes. + */ + + attrs: function(attrs){ + var buf = [] + , classes = [] + , escaped = {} + , constant = attrs.every(function(attr){ return isConstant(attr.val) }) + , inherits = false; + + if (this.terse) buf.push('terse: true'); + + attrs.forEach(function(attr){ + if (attr.name == 'attributes') return inherits = true; + escaped[attr.name] = attr.escaped; + if (attr.name == 'class') { + classes.push('(' + attr.val + ')'); + } else { + var pair = "'" + attr.name + "':(" + attr.val + ')'; + buf.push(pair); + } + }); + + if (classes.length) { + classes = classes.join(" + ' ' + "); + buf.push("class: " + classes); + } + + return { + buf: buf.join(', ').replace('class:', '"class":'), + escaped: JSON.stringify(escaped), + inherits: inherits, + constant: constant + }; + } +}; + +/** + * Check if expression can be evaluated to a constant + * + * @param {String} expression + * @return {Boolean} + * @api private + */ + +function isConstant(val){ + // Check strings/literals + if (/^ *("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|true|false|null|undefined) *$/i.test(val)) + return true; + + // Check numbers + if (!isNaN(Number(val))) + return true; + + // Check arrays + var matches; + if (matches = /^ *\[(.*)\] *$/.exec(val)) + return matches[1].split(',').every(isConstant); + + return false; +} + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} +}); // module: compiler.js + +require.register("doctypes.js", function(module, exports, require){ + +/*! + * Jade - doctypes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + '5': '' + , 'default': '' + , 'xml': '' + , 'transitional': '' + , 'strict': '' + , 'frameset': '' + , '1.1': '' + , 'basic': '' + , 'mobile': '' +}; +}); // module: doctypes.js + +require.register("filters.js", function(module, exports, require){ + +/*! + * Jade - filters + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + + /** + * Wrap text with CDATA block. + */ + + cdata: function(str){ + return ''; + }, + + /** + * Transform sass to css, wrapped in style tags. + */ + + sass: function(str){ + str = str.replace(/\\n/g, '\n'); + var sass = require('sass').render(str).replace(/\n/g, '\\n'); + return ''; + }, + + /** + * Transform stylus to css, wrapped in style tags. + */ + + stylus: function(str, options){ + var ret; + str = str.replace(/\\n/g, '\n'); + var stylus = require('stylus'); + stylus(str, options).render(function(err, css){ + if (err) throw err; + ret = css.replace(/\n/g, '\\n'); + }); + return ''; + }, + + /** + * Transform less to css, wrapped in style tags. + */ + + less: function(str){ + var ret; + str = str.replace(/\\n/g, '\n'); + require('less').render(str, function(err, css){ + if (err) throw err; + ret = ''; + }); + return ret; + }, + + /** + * Transform markdown to html. + */ + + markdown: function(str){ + var md; + + // support markdown / discount + try { + md = require('markdown'); + } catch (err){ + try { + md = require('discount'); + } catch (err) { + try { + md = require('markdown-js'); + } catch (err) { + try { + md = require('marked'); + } catch (err) { + throw new + Error('Cannot find markdown library, install markdown, discount, or marked.'); + } + } + } + } + + str = str.replace(/\\n/g, '\n'); + return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'''); + }, + + /** + * Transform coffeescript to javascript. + */ + + coffeescript: function(str){ + str = str.replace(/\\n/g, '\n'); + var js = require('coffee-script').compile(str).replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); + return ''; + } +}; + +}); // module: filters.js + +require.register("inline-tags.js", function(module, exports, require){ + +/*! + * Jade - inline tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'a' + , 'abbr' + , 'acronym' + , 'b' + , 'br' + , 'code' + , 'em' + , 'font' + , 'i' + , 'img' + , 'ins' + , 'kbd' + , 'map' + , 'samp' + , 'small' + , 'span' + , 'strong' + , 'sub' + , 'sup' +]; +}); // module: inline-tags.js + +require.register("jade.js", function(module, exports, require){ +/*! + * Jade + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Parser = require('./parser') + , Lexer = require('./lexer') + , Compiler = require('./compiler') + , runtime = require('./runtime') + +/** + * Library version. + */ + +exports.version = '0.26.1'; + +/** + * Expose self closing tags. + */ + +exports.selfClosing = require('./self-closing'); + +/** + * Default supported doctypes. + */ + +exports.doctypes = require('./doctypes'); + +/** + * Text filters. + */ + +exports.filters = require('./filters'); + +/** + * Utilities. + */ + +exports.utils = require('./utils'); + +/** + * Expose `Compiler`. + */ + +exports.Compiler = Compiler; + +/** + * Expose `Parser`. + */ + +exports.Parser = Parser; + +/** + * Expose `Lexer`. + */ + +exports.Lexer = Lexer; + +/** + * Nodes. + */ + +exports.nodes = require('./nodes'); + +/** + * Jade runtime helpers. + */ + +exports.runtime = runtime; + +/** + * Template function cache. + */ + +exports.cache = {}; + +/** + * Parse the given `str` of jade and return a function body. + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api private + */ + +function parse(str, options){ + try { + // Parse + var parser = new Parser(str, options.filename, options); + + // Compile + var compiler = new (options.compiler || Compiler)(parser.parse(), options) + , js = compiler.compile(); + + // Debug compiler + if (options.debug) { + console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' ')); + } + + return '' + + 'var buf = [];\n' + + (options.self + ? 'var self = locals || {};\n' + js + : 'with (locals || {}) {\n' + js + '\n}\n') + + 'return buf.join("");'; + } catch (err) { + parser = parser.context(); + runtime.rethrow(err, parser.filename, parser.lexer.lineno); + } +} + +/** + * Compile a `Function` representation of the given jade `str`. + * + * Options: + * + * - `compileDebug` when `false` debugging code is stripped from the compiled template + * - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()` + * for use with the Jade client-side runtime.js + * + * @param {String} str + * @param {Options} options + * @return {Function} + * @api public + */ + +exports.compile = function(str, options){ + var options = options || {} + , client = options.client + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined' + , fn; + + if (options.compileDebug !== false) { + fn = [ + 'var __jade = [{ lineno: 1, filename: ' + filename + ' }];' + , 'try {' + , parse(String(str), options) + , '} catch (err) {' + , ' rethrow(err, __jade[0].filename, __jade[0].lineno);' + , '}' + ].join('\n'); + } else { + fn = parse(String(str), options); + } + + if (client) { + fn = 'attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;\n' + fn; + } + + fn = new Function('locals, attrs, escape, rethrow, merge', fn); + + if (client) return fn; + + return function(locals){ + return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow, runtime.merge); + }; +}; + +/** + * Render the given `str` of jade and invoke + * the callback `fn(err, str)`. + * + * Options: + * + * - `cache` enable template caching + * - `filename` filename required for `include` / `extends` and caching + * + * @param {String} str + * @param {Object|Function} options or fn + * @param {Function} fn + * @api public + */ + +exports.render = function(str, options, fn){ + // swap args + if ('function' == typeof options) { + fn = options, options = {}; + } + + // cache requires .filename + if (options.cache && !options.filename) { + return fn(new Error('the "filename" option is required for caching')); + } + + try { + var path = options.filename; + var tmpl = options.cache + ? exports.cache[path] || (exports.cache[path] = exports.compile(str, options)) + : exports.compile(str, options); + fn(null, tmpl(options)); + } catch (err) { + fn(err); + } +}; + +/** + * Render a Jade file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + try { + options.filename = path; + var str = options.cache + ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + exports.render(str, options, fn); + } catch (err) { + fn(err); + } +}; + +/** + * Express support. + */ + +exports.__express = exports.renderFile; + +}); // module: jade.js + +require.register("lexer.js", function(module, exports, require){ + +/*! + * Jade - Lexer + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize `Lexer` with the given `str`. + * + * Options: + * + * - `colons` allow colons for attr delimiters + * + * @param {String} str + * @param {Object} options + * @api private + */ + +var Lexer = module.exports = function Lexer(str, options) { + options = options || {}; + this.input = str.replace(/\r\n|\r/g, '\n'); + this.colons = options.colons; + this.deferredTokens = []; + this.lastIndents = 0; + this.lineno = 1; + this.stash = []; + this.indentStack = []; + this.indentRe = null; + this.pipeless = false; +}; + +/** + * Lexer prototype. + */ + +Lexer.prototype = { + + /** + * Construct a token with the given `type` and `val`. + * + * @param {String} type + * @param {String} val + * @return {Object} + * @api private + */ + + tok: function(type, val){ + return { + type: type + , line: this.lineno + , val: val + } + }, + + /** + * Consume the given `len` of input. + * + * @param {Number} len + * @api private + */ + + consume: function(len){ + this.input = this.input.substr(len); + }, + + /** + * Scan for `type` with the given `regexp`. + * + * @param {String} type + * @param {RegExp} regexp + * @return {Object} + * @api private + */ + + scan: function(regexp, type){ + var captures; + if (captures = regexp.exec(this.input)) { + this.consume(captures[0].length); + return this.tok(type, captures[1]); + } + }, + + /** + * Defer the given `tok`. + * + * @param {Object} tok + * @api private + */ + + defer: function(tok){ + this.deferredTokens.push(tok); + }, + + /** + * Lookahead `n` tokens. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + var fetch = n - this.stash.length; + while (fetch-- > 0) this.stash.push(this.next()); + return this.stash[--n]; + }, + + /** + * Return the indexOf `start` / `end` delimiters. + * + * @param {String} start + * @param {String} end + * @return {Number} + * @api private + */ + + indexOfDelimiters: function(start, end){ + var str = this.input + , nstart = 0 + , nend = 0 + , pos = 0; + for (var i = 0, len = str.length; i < len; ++i) { + if (start == str.charAt(i)) { + ++nstart; + } else if (end == str.charAt(i)) { + if (++nend == nstart) { + pos = i; + break; + } + } + } + return pos; + }, + + /** + * Stashed token. + */ + + stashed: function() { + return this.stash.length + && this.stash.shift(); + }, + + /** + * Deferred token. + */ + + deferred: function() { + return this.deferredTokens.length + && this.deferredTokens.shift(); + }, + + /** + * end-of-source. + */ + + eos: function() { + if (this.input.length) return; + if (this.indentStack.length) { + this.indentStack.shift(); + return this.tok('outdent'); + } else { + return this.tok('eos'); + } + }, + + /** + * Blank line. + */ + + blank: function() { + var captures; + if (captures = /^\n *\n/.exec(this.input)) { + this.consume(captures[0].length - 1); + if (this.pipeless) return this.tok('text', ''); + return this.next(); + } + }, + + /** + * Comment. + */ + + comment: function() { + var captures; + if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('comment', captures[2]); + tok.buffer = '-' != captures[1]; + return tok; + } + }, + + /** + * Interpolated tag. + */ + + interpolation: function() { + var captures; + if (captures = /^#\{(.*?)\}/.exec(this.input)) { + this.consume(captures[0].length); + return this.tok('interpolation', captures[1]); + } + }, + + /** + * Tag. + */ + + tag: function() { + var captures; + if (captures = /^(\w[-:\w]*)(\/?)/.exec(this.input)) { + this.consume(captures[0].length); + var tok, name = captures[1]; + if (':' == name[name.length - 1]) { + name = name.slice(0, -1); + tok = this.tok('tag', name); + this.defer(this.tok(':')); + while (' ' == this.input[0]) this.input = this.input.substr(1); + } else { + tok = this.tok('tag', name); + } + tok.selfClosing = !! captures[2]; + return tok; + } + }, + + /** + * Filter. + */ + + filter: function() { + return this.scan(/^:(\w+)/, 'filter'); + }, + + /** + * Doctype. + */ + + doctype: function() { + return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype'); + }, + + /** + * Id. + */ + + id: function() { + return this.scan(/^#([\w-]+)/, 'id'); + }, + + /** + * Class. + */ + + className: function() { + return this.scan(/^\.([\w-]+)/, 'class'); + }, + + /** + * Text. + */ + + text: function() { + return this.scan(/^(?:\| ?| ?)?([^\n]+)/, 'text'); + }, + + /** + * Extends. + */ + + "extends": function() { + return this.scan(/^extends? +([^\n]+)/, 'extends'); + }, + + /** + * Block prepend. + */ + + prepend: function() { + var captures; + if (captures = /^prepend +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var mode = 'prepend' + , name = captures[1] + , tok = this.tok('block', name); + tok.mode = mode; + return tok; + } + }, + + /** + * Block append. + */ + + append: function() { + var captures; + if (captures = /^append +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var mode = 'append' + , name = captures[1] + , tok = this.tok('block', name); + tok.mode = mode; + return tok; + } + }, + + /** + * Block. + */ + + block: function() { + var captures; + if (captures = /^block\b *(?:(prepend|append) +)?([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var mode = captures[1] || 'replace' + , name = captures[2] + , tok = this.tok('block', name); + + tok.mode = mode; + return tok; + } + }, + + /** + * Yield. + */ + + yield: function() { + return this.scan(/^yield */, 'yield'); + }, + + /** + * Include. + */ + + include: function() { + return this.scan(/^include +([^\n]+)/, 'include'); + }, + + /** + * Case. + */ + + "case": function() { + return this.scan(/^case +([^\n]+)/, 'case'); + }, + + /** + * When. + */ + + when: function() { + return this.scan(/^when +([^:\n]+)/, 'when'); + }, + + /** + * Default. + */ + + "default": function() { + return this.scan(/^default */, 'default'); + }, + + /** + * Assignment. + */ + + assignment: function() { + var captures; + if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) { + this.consume(captures[0].length); + var name = captures[1] + , val = captures[2]; + return this.tok('code', 'var ' + name + ' = (' + val + ');'); + } + }, + + /** + * Call mixin. + */ + + call: function(){ + var captures; + if (captures = /^\+([-\w]+)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('call', captures[1]); + + // Check for args (not attributes) + if (captures = /^ *\((.*?)\)/.exec(this.input)) { + if (!/^ *[-\w]+ *=/.test(captures[1])) { + this.consume(captures[0].length); + tok.args = captures[1]; + } + } + + return tok; + } + }, + + /** + * Mixin. + */ + + mixin: function(){ + var captures; + if (captures = /^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('mixin', captures[1]); + tok.args = captures[2]; + return tok; + } + }, + + /** + * Conditional. + */ + + conditional: function() { + var captures; + if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var type = captures[1] + , js = captures[2]; + + switch (type) { + case 'if': js = 'if (' + js + ')'; break; + case 'unless': js = 'if (!(' + js + '))'; break; + case 'else if': js = 'else if (' + js + ')'; break; + case 'else': js = 'else'; break; + } + + return this.tok('code', js); + } + }, + + /** + * While. + */ + + "while": function() { + var captures; + if (captures = /^while +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + return this.tok('code', 'while (' + captures[1] + ')'); + } + }, + + /** + * Each. + */ + + each: function() { + var captures; + if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('each', captures[1]); + tok.key = captures[2] || '$index'; + tok.code = captures[3]; + return tok; + } + }, + + /** + * Code. + */ + + code: function() { + var captures; + if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var flags = captures[1]; + captures[1] = captures[2]; + var tok = this.tok('code', captures[1]); + tok.escape = flags[0] === '='; + tok.buffer = flags[0] === '=' || flags[1] === '='; + return tok; + } + }, + + /** + * Attributes. + */ + + attrs: function() { + if ('(' == this.input.charAt(0)) { + var index = this.indexOfDelimiters('(', ')') + , str = this.input.substr(1, index-1) + , tok = this.tok('attrs') + , len = str.length + , colons = this.colons + , states = ['key'] + , escapedAttr + , key = '' + , val = '' + , quote + , c + , p; + + function state(){ + return states[states.length - 1]; + } + + function interpolate(attr) { + return attr.replace(/#\{([^}]+)\}/g, function(_, expr){ + return quote + " + (" + expr + ") + " + quote; + }); + } + + this.consume(index + 1); + tok.attrs = {}; + tok.escaped = {}; + + function parse(c) { + var real = c; + // TODO: remove when people fix ":" + if (colons && ':' == c) c = '='; + switch (c) { + case ',': + case '\n': + switch (state()) { + case 'expr': + case 'array': + case 'string': + case 'object': + val += c; + break; + default: + states.push('key'); + val = val.trim(); + key = key.trim(); + if ('' == key) return; + key = key.replace(/^['"]|['"]$/g, '').replace('!', ''); + tok.escaped[key] = escapedAttr; + tok.attrs[key] = '' == val + ? true + : interpolate(val); + key = val = ''; + } + break; + case '=': + switch (state()) { + case 'key char': + key += real; + break; + case 'val': + case 'expr': + case 'array': + case 'string': + case 'object': + val += real; + break; + default: + escapedAttr = '!' != p; + states.push('val'); + } + break; + case '(': + if ('val' == state() + || 'expr' == state()) states.push('expr'); + val += c; + break; + case ')': + if ('expr' == state() + || 'val' == state()) states.pop(); + val += c; + break; + case '{': + if ('val' == state()) states.push('object'); + val += c; + break; + case '}': + if ('object' == state()) states.pop(); + val += c; + break; + case '[': + if ('val' == state()) states.push('array'); + val += c; + break; + case ']': + if ('array' == state()) states.pop(); + val += c; + break; + case '"': + case "'": + switch (state()) { + case 'key': + states.push('key char'); + break; + case 'key char': + states.pop(); + break; + case 'string': + if (c == quote) states.pop(); + val += c; + break; + default: + states.push('string'); + val += c; + quote = c; + } + break; + case '': + break; + default: + switch (state()) { + case 'key': + case 'key char': + key += c; + break; + default: + val += c; + } + } + p = c; + } + + for (var i = 0; i < len; ++i) { + parse(str.charAt(i)); + } + + parse(','); + + if ('/' == this.input.charAt(0)) { + this.consume(1); + tok.selfClosing = true; + } + + return tok; + } + }, + + /** + * Indent | Outdent | Newline. + */ + + indent: function() { + var captures, re; + + // established regexp + if (this.indentRe) { + captures = this.indentRe.exec(this.input); + // determine regexp + } else { + // tabs + re = /^\n(\t*) */; + captures = re.exec(this.input); + + // spaces + if (captures && !captures[1].length) { + re = /^\n( *)/; + captures = re.exec(this.input); + } + + // established + if (captures && captures[1].length) this.indentRe = re; + } + + if (captures) { + var tok + , indents = captures[1].length; + + ++this.lineno; + this.consume(indents + 1); + + if (' ' == this.input[0] || '\t' == this.input[0]) { + throw new Error('Invalid indentation, you can use tabs or spaces but not both'); + } + + // blank line + if ('\n' == this.input[0]) return this.tok('newline'); + + // outdent + if (this.indentStack.length && indents < this.indentStack[0]) { + while (this.indentStack.length && this.indentStack[0] > indents) { + this.stash.push(this.tok('outdent')); + this.indentStack.shift(); + } + tok = this.stash.pop(); + // indent + } else if (indents && indents != this.indentStack[0]) { + this.indentStack.unshift(indents); + tok = this.tok('indent', indents); + // newline + } else { + tok = this.tok('newline'); + } + + return tok; + } + }, + + /** + * Pipe-less text consumed only when + * pipeless is true; + */ + + pipelessText: function() { + if (this.pipeless) { + if ('\n' == this.input[0]) return; + var i = this.input.indexOf('\n'); + if (-1 == i) i = this.input.length; + var str = this.input.substr(0, i); + this.consume(str.length); + return this.tok('text', str); + } + }, + + /** + * ':' + */ + + colon: function() { + return this.scan(/^: */, ':'); + }, + + /** + * Return the next token object, or those + * previously stashed by lookahead. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.stashed() + || this.next(); + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + next: function() { + return this.deferred() + || this.blank() + || this.eos() + || this.pipelessText() + || this.yield() + || this.doctype() + || this.interpolation() + || this["case"]() + || this.when() + || this["default"]() + || this["extends"]() + || this.append() + || this.prepend() + || this.block() + || this.include() + || this.mixin() + || this.call() + || this.conditional() + || this.each() + || this["while"]() + || this.assignment() + || this.tag() + || this.filter() + || this.code() + || this.id() + || this.className() + || this.attrs() + || this.indent() + || this.comment() + || this.colon() + || this.text(); + } +}; + +}); // module: lexer.js + +require.register("nodes/attrs.js", function(module, exports, require){ + +/*! + * Jade - nodes - Attrs + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'), + Block = require('./block'); + +/** + * Initialize a `Attrs` node. + * + * @api public + */ + +var Attrs = module.exports = function Attrs() { + this.attrs = []; +}; + +/** + * Inherit from `Node`. + */ + +Attrs.prototype = new Node; +Attrs.prototype.constructor = Attrs; + + +/** + * Set attribute `name` to `val`, keep in mind these become + * part of a raw js object literal, so to quote a value you must + * '"quote me"', otherwise or example 'user.name' is literal JavaScript. + * + * @param {String} name + * @param {String} val + * @param {Boolean} escaped + * @return {Tag} for chaining + * @api public + */ + +Attrs.prototype.setAttribute = function(name, val, escaped){ + this.attrs.push({ name: name, val: val, escaped: escaped }); + return this; +}; + +/** + * Remove attribute `name` when present. + * + * @param {String} name + * @api public + */ + +Attrs.prototype.removeAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + delete this.attrs[i]; + } + } +}; + +/** + * Get attribute value by `name`. + * + * @param {String} name + * @return {String} + * @api public + */ + +Attrs.prototype.getAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + return this.attrs[i].val; + } + } +}; + +}); // module: nodes/attrs.js + +require.register("nodes/block-comment.js", function(module, exports, require){ + +/*! + * Jade - nodes - BlockComment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `BlockComment` with the given `block`. + * + * @param {String} val + * @param {Block} block + * @param {Boolean} buffer + * @api public + */ + +var BlockComment = module.exports = function BlockComment(val, block, buffer) { + this.block = block; + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +BlockComment.prototype = new Node; +BlockComment.prototype.constructor = BlockComment; + +}); // module: nodes/block-comment.js + +require.register("nodes/block.js", function(module, exports, require){ + +/*! + * Jade - nodes - Block + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Block` with an optional `node`. + * + * @param {Node} node + * @api public + */ + +var Block = module.exports = function Block(node){ + this.nodes = []; + if (node) this.push(node); +}; + +/** + * Inherit from `Node`. + */ + +Block.prototype = new Node; +Block.prototype.constructor = Block; + + +/** + * Block flag. + */ + +Block.prototype.isBlock = true; + +/** + * Replace the nodes in `other` with the nodes + * in `this` block. + * + * @param {Block} other + * @api private + */ + +Block.prototype.replace = function(other){ + other.nodes = this.nodes; +}; + +/** + * Pust the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.push = function(node){ + return this.nodes.push(node); +}; + +/** + * Check if this block is empty. + * + * @return {Boolean} + * @api public + */ + +Block.prototype.isEmpty = function(){ + return 0 == this.nodes.length; +}; + +/** + * Unshift the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.unshift = function(node){ + return this.nodes.unshift(node); +}; + +/** + * Return the "last" block, or the first `yield` node. + * + * @return {Block} + * @api private + */ + +Block.prototype.includeBlock = function(){ + var ret = this + , node; + + for (var i = 0, len = this.nodes.length; i < len; ++i) { + node = this.nodes[i]; + if (node.yield) return node; + else if (node.textOnly) continue; + else if (node.includeBlock) ret = node.includeBlock(); + else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock(); + } + + return ret; +}; + +/** + * Return a clone of this block. + * + * @return {Block} + * @api private + */ + +Block.prototype.clone = function(){ + var clone = new Block; + for (var i = 0, len = this.nodes.length; i < len; ++i) { + clone.push(this.nodes[i].clone()); + } + return clone; +}; + + +}); // module: nodes/block.js + +require.register("nodes/case.js", function(module, exports, require){ + +/*! + * Jade - nodes - Case + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Case` with `expr`. + * + * @param {String} expr + * @api public + */ + +var Case = exports = module.exports = function Case(expr, block){ + this.expr = expr; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Case.prototype = new Node; +Case.prototype.constructor = Case; + + +var When = exports.When = function When(expr, block){ + this.expr = expr; + this.block = block; + this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +When.prototype = new Node; +When.prototype.constructor = When; + + + +}); // module: nodes/case.js + +require.register("nodes/code.js", function(module, exports, require){ + +/*! + * Jade - nodes - Code + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Code` node with the given code `val`. + * Code may also be optionally buffered and escaped. + * + * @param {String} val + * @param {Boolean} buffer + * @param {Boolean} escape + * @api public + */ + +var Code = module.exports = function Code(val, buffer, escape) { + this.val = val; + this.buffer = buffer; + this.escape = escape; + if (val.match(/^ *else/)) this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +Code.prototype = new Node; +Code.prototype.constructor = Code; + +}); // module: nodes/code.js + +require.register("nodes/comment.js", function(module, exports, require){ + +/*! + * Jade - nodes - Comment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Comment` with the given `val`, optionally `buffer`, + * otherwise the comment may render in the output. + * + * @param {String} val + * @param {Boolean} buffer + * @api public + */ + +var Comment = module.exports = function Comment(val, buffer) { + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +Comment.prototype = new Node; +Comment.prototype.constructor = Comment; + +}); // module: nodes/comment.js + +require.register("nodes/doctype.js", function(module, exports, require){ + +/*! + * Jade - nodes - Doctype + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Doctype` with the given `val`. + * + * @param {String} val + * @api public + */ + +var Doctype = module.exports = function Doctype(val) { + this.val = val; +}; + +/** + * Inherit from `Node`. + */ + +Doctype.prototype = new Node; +Doctype.prototype.constructor = Doctype; + +}); // module: nodes/doctype.js + +require.register("nodes/each.js", function(module, exports, require){ + +/*! + * Jade - nodes - Each + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize an `Each` node, representing iteration + * + * @param {String} obj + * @param {String} val + * @param {String} key + * @param {Block} block + * @api public + */ + +var Each = module.exports = function Each(obj, val, key, block) { + this.obj = obj; + this.val = val; + this.key = key; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Each.prototype = new Node; +Each.prototype.constructor = Each; + +}); // module: nodes/each.js + +require.register("nodes/filter.js", function(module, exports, require){ + +/*! + * Jade - nodes - Filter + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , Block = require('./block'); + +/** + * Initialize a `Filter` node with the given + * filter `name` and `block`. + * + * @param {String} name + * @param {Block|Node} block + * @api public + */ + +var Filter = module.exports = function Filter(name, block, attrs) { + this.name = name; + this.block = block; + this.attrs = attrs; + this.isASTFilter = !block.nodes.every(function(node){ return node.isText }); +}; + +/** + * Inherit from `Node`. + */ + +Filter.prototype = new Node; +Filter.prototype.constructor = Filter; + +}); // module: nodes/filter.js + +require.register("nodes/index.js", function(module, exports, require){ + +/*! + * Jade - nodes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +exports.Node = require('./node'); +exports.Tag = require('./tag'); +exports.Code = require('./code'); +exports.Each = require('./each'); +exports.Case = require('./case'); +exports.Text = require('./text'); +exports.Block = require('./block'); +exports.Mixin = require('./mixin'); +exports.Filter = require('./filter'); +exports.Comment = require('./comment'); +exports.Literal = require('./literal'); +exports.BlockComment = require('./block-comment'); +exports.Doctype = require('./doctype'); + +}); // module: nodes/index.js + +require.register("nodes/literal.js", function(module, exports, require){ + +/*! + * Jade - nodes - Literal + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Literal` node with the given `str. + * + * @param {String} str + * @api public + */ + +var Literal = module.exports = function Literal(str) { + this.str = str + .replace(/\\/g, "\\\\") + .replace(/\n|\r\n/g, "\\n") + .replace(/'/g, "\\'"); +}; + +/** + * Inherit from `Node`. + */ + +Literal.prototype = new Node; +Literal.prototype.constructor = Literal; + + +}); // module: nodes/literal.js + +require.register("nodes/mixin.js", function(module, exports, require){ + +/*! + * Jade - nodes - Mixin + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Attrs = require('./attrs'); + +/** + * Initialize a new `Mixin` with `name` and `block`. + * + * @param {String} name + * @param {String} args + * @param {Block} block + * @api public + */ + +var Mixin = module.exports = function Mixin(name, args, block, call){ + this.name = name; + this.args = args; + this.block = block; + this.attrs = []; + this.call = call; +}; + +/** + * Inherit from `Attrs`. + */ + +Mixin.prototype = new Attrs; +Mixin.prototype.constructor = Mixin; + + + +}); // module: nodes/mixin.js + +require.register("nodes/node.js", function(module, exports, require){ + +/*! + * Jade - nodes - Node + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize a `Node`. + * + * @api public + */ + +var Node = module.exports = function Node(){}; + +/** + * Clone this node (return itself) + * + * @return {Node} + * @api private + */ + +Node.prototype.clone = function(){ + return this; +}; + +}); // module: nodes/node.js + +require.register("nodes/tag.js", function(module, exports, require){ + +/*! + * Jade - nodes - Tag + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Attrs = require('./attrs'), + Block = require('./block'), + inlineTags = require('../inline-tags'); + +/** + * Initialize a `Tag` node with the given tag `name` and optional `block`. + * + * @param {String} name + * @param {Block} block + * @api public + */ + +var Tag = module.exports = function Tag(name, block) { + this.name = name; + this.attrs = []; + this.block = block || new Block; +}; + +/** + * Inherit from `Attrs`. + */ + +Tag.prototype = new Attrs; +Tag.prototype.constructor = Tag; + + +/** + * Clone this tag. + * + * @return {Tag} + * @api private + */ + +Tag.prototype.clone = function(){ + var clone = new Tag(this.name, this.block.clone()); + clone.line = this.line; + clone.attrs = this.attrs; + clone.textOnly = this.textOnly; + return clone; +}; + +/** + * Check if this tag is an inline tag. + * + * @return {Boolean} + * @api private + */ + +Tag.prototype.isInline = function(){ + return ~inlineTags.indexOf(this.name); +}; + +/** + * Check if this tag's contents can be inlined. Used for pretty printing. + * + * @return {Boolean} + * @api private + */ + +Tag.prototype.canInline = function(){ + var nodes = this.block.nodes; + + function isInline(node){ + // Recurse if the node is a block + if (node.isBlock) return node.nodes.every(isInline); + return node.isText || (node.isInline && node.isInline()); + } + + // Empty tag + if (!nodes.length) return true; + + // Text-only or inline-only tag + if (1 == nodes.length) return isInline(nodes[0]); + + // Multi-line inline-only tag + if (this.block.nodes.every(isInline)) { + for (var i = 1, len = nodes.length; i < len; ++i) { + if (nodes[i-1].isText && nodes[i].isText) + return false; + } + return true; + } + + // Mixed tag + return false; +}; +}); // module: nodes/tag.js + +require.register("nodes/text.js", function(module, exports, require){ + +/*! + * Jade - nodes - Text + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Text` node with optional `line`. + * + * @param {String} line + * @api public + */ + +var Text = module.exports = function Text(line) { + this.val = ''; + if ('string' == typeof line) this.val = line; +}; + +/** + * Inherit from `Node`. + */ + +Text.prototype = new Node; +Text.prototype.constructor = Text; + + +/** + * Flag as text. + */ + +Text.prototype.isText = true; +}); // module: nodes/text.js + +require.register("parser.js", function(module, exports, require){ + +/*! + * Jade - Parser + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Lexer = require('./lexer') + , nodes = require('./nodes'); + +/** + * Initialize `Parser` with the given input `str` and `filename`. + * + * @param {String} str + * @param {String} filename + * @param {Object} options + * @api public + */ + +var Parser = exports = module.exports = function Parser(str, filename, options){ + this.input = str; + this.lexer = new Lexer(str, options); + this.filename = filename; + this.blocks = {}; + this.mixins = {}; + this.options = options; + this.contexts = [this]; +}; + +/** + * Tags that may not contain tags. + */ + +var textOnly = exports.textOnly = ['script', 'style']; + +/** + * Parser prototype. + */ + +Parser.prototype = { + + /** + * Push `parser` onto the context stack, + * or pop and return a `Parser`. + */ + + context: function(parser){ + if (parser) { + this.contexts.push(parser); + } else { + return this.contexts.pop(); + } + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.lexer.advance(); + }, + + /** + * Skip `n` tokens. + * + * @param {Number} n + * @api private + */ + + skip: function(n){ + while (n--) this.advance(); + }, + + /** + * Single token lookahead. + * + * @return {Object} + * @api private + */ + + peek: function() { + return this.lookahead(1); + }, + + /** + * Return lexer lineno. + * + * @return {Number} + * @api private + */ + + line: function() { + return this.lexer.lineno; + }, + + /** + * `n` token lookahead. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + return this.lexer.lookahead(n); + }, + + /** + * Parse input returning a string of js for evaluation. + * + * @return {String} + * @api public + */ + + parse: function(){ + var block = new nodes.Block, parser; + block.line = this.line(); + + while ('eos' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + + if (parser = this.extending) { + this.context(parser); + var ast = parser.parse(); + this.context(); + // hoist mixins + for (var name in this.mixins) + ast.unshift(this.mixins[name]); + return ast; + } + + return block; + }, + + /** + * Expect the given type, or throw an exception. + * + * @param {String} type + * @api private + */ + + expect: function(type){ + if (this.peek().type === type) { + return this.advance(); + } else { + throw new Error('expected "' + type + '", but got "' + this.peek().type + '"'); + } + }, + + /** + * Accept the given `type`. + * + * @param {String} type + * @api private + */ + + accept: function(type){ + if (this.peek().type === type) { + return this.advance(); + } + }, + + /** + * tag + * | doctype + * | mixin + * | include + * | filter + * | comment + * | text + * | each + * | code + * | yield + * | id + * | class + * | interpolation + */ + + parseExpr: function(){ + switch (this.peek().type) { + case 'tag': + return this.parseTag(); + case 'mixin': + return this.parseMixin(); + case 'block': + return this.parseBlock(); + case 'case': + return this.parseCase(); + case 'when': + return this.parseWhen(); + case 'default': + return this.parseDefault(); + case 'extends': + return this.parseExtends(); + case 'include': + return this.parseInclude(); + case 'doctype': + return this.parseDoctype(); + case 'filter': + return this.parseFilter(); + case 'comment': + return this.parseComment(); + case 'text': + return this.parseText(); + case 'each': + return this.parseEach(); + case 'code': + return this.parseCode(); + case 'call': + return this.parseCall(); + case 'interpolation': + return this.parseInterpolation(); + case 'yield': + this.advance(); + var block = new nodes.Block; + block.yield = true; + return block; + case 'id': + case 'class': + var tok = this.advance(); + this.lexer.defer(this.lexer.tok('tag', 'div')); + this.lexer.defer(tok); + return this.parseExpr(); + default: + throw new Error('unexpected token "' + this.peek().type + '"'); + } + }, + + /** + * Text + */ + + parseText: function(){ + var tok = this.expect('text') + , node = new nodes.Text(tok.val); + node.line = this.line(); + return node; + }, + + /** + * ':' expr + * | block + */ + + parseBlockExpansion: function(){ + if (':' == this.peek().type) { + this.advance(); + return new nodes.Block(this.parseExpr()); + } else { + return this.block(); + } + }, + + /** + * case + */ + + parseCase: function(){ + var val = this.expect('case').val + , node = new nodes.Case(val); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * when + */ + + parseWhen: function(){ + var val = this.expect('when').val + return new nodes.Case.When(val, this.parseBlockExpansion()); + }, + + /** + * default + */ + + parseDefault: function(){ + this.expect('default'); + return new nodes.Case.When('default', this.parseBlockExpansion()); + }, + + /** + * code + */ + + parseCode: function(){ + var tok = this.expect('code') + , node = new nodes.Code(tok.val, tok.buffer, tok.escape) + , block + , i = 1; + node.line = this.line(); + while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i; + block = 'indent' == this.lookahead(i).type; + if (block) { + this.skip(i-1); + node.block = this.block(); + } + return node; + }, + + /** + * comment + */ + + parseComment: function(){ + var tok = this.expect('comment') + , node; + + if ('indent' == this.peek().type) { + node = new nodes.BlockComment(tok.val, this.block(), tok.buffer); + } else { + node = new nodes.Comment(tok.val, tok.buffer); + } + + node.line = this.line(); + return node; + }, + + /** + * doctype + */ + + parseDoctype: function(){ + var tok = this.expect('doctype') + , node = new nodes.Doctype(tok.val); + node.line = this.line(); + return node; + }, + + /** + * filter attrs? text-block + */ + + parseFilter: function(){ + var block + , tok = this.expect('filter') + , attrs = this.accept('attrs'); + + this.lexer.pipeless = true; + block = this.parseTextBlock(); + this.lexer.pipeless = false; + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * tag ':' attrs? block + */ + + parseASTFilter: function(){ + var block + , tok = this.expect('tag') + , attrs = this.accept('attrs'); + + this.expect(':'); + block = this.block(); + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * each block + */ + + parseEach: function(){ + var tok = this.expect('each') + , node = new nodes.Each(tok.code, tok.val, tok.key); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * 'extends' name + */ + + parseExtends: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + if (!this.filename) + throw new Error('the "filename" option is required to extend templates'); + + var path = this.expect('extends').val.trim() + , dir = dirname(this.filename); + + var path = join(dir, path + '.jade') + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + + parser.blocks = this.blocks; + parser.contexts = this.contexts; + this.extending = parser; + + // TODO: null node + return new nodes.Literal(''); + }, + + /** + * 'block' name block + */ + + parseBlock: function(){ + var block = this.expect('block') + , mode = block.mode + , name = block.val.trim(); + + block = 'indent' == this.peek().type + ? this.block() + : new nodes.Block(new nodes.Literal('')); + + var prev = this.blocks[name]; + + if (prev) { + switch (prev.mode) { + case 'append': + block.nodes = block.nodes.concat(prev.nodes); + prev = block; + break; + case 'prepend': + block.nodes = prev.nodes.concat(block.nodes); + prev = block; + break; + } + } + + block.mode = mode; + return this.blocks[name] = prev || block; + }, + + /** + * include block? + */ + + parseInclude: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + var path = this.expect('include').val.trim() + , dir = dirname(this.filename); + + if (!this.filename) + throw new Error('the "filename" option is required to use includes'); + + // no extension + if (!~basename(path).indexOf('.')) { + path += '.jade'; + } + + // non-jade + if ('.jade' != path.substr(-5)) { + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8'); + return new nodes.Literal(str); + } + + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + parser.blocks = this.blocks; + parser.mixins = this.mixins; + + this.context(parser); + var ast = parser.parse(); + this.context(); + ast.filename = path; + + if ('indent' == this.peek().type) { + ast.includeBlock().push(this.block()); + } + + return ast; + }, + + /** + * call ident block + */ + + parseCall: function(){ + var tok = this.expect('call') + , name = tok.val + , args = tok.args + , mixin = new nodes.Mixin(name, args, new nodes.Block, true); + + this.tag(mixin); + if (mixin.block.isEmpty()) mixin.block = null; + return mixin; + }, + + /** + * mixin block + */ + + parseMixin: function(){ + var tok = this.expect('mixin') + , name = tok.val + , args = tok.args + , mixin; + + // definition + if ('indent' == this.peek().type) { + mixin = new nodes.Mixin(name, args, this.block(), false); + this.mixins[name] = mixin; + return mixin; + // call + } else { + return new nodes.Mixin(name, args, null, true); + } + }, + + /** + * indent (text | newline)* outdent + */ + + parseTextBlock: function(){ + var block = new nodes.Block; + block.line = this.line(); + var spaces = this.expect('indent').val; + if (null == this._spaces) this._spaces = spaces; + var indent = Array(spaces - this._spaces + 1).join(' '); + while ('outdent' != this.peek().type) { + switch (this.peek().type) { + case 'newline': + this.advance(); + break; + case 'indent': + this.parseTextBlock().nodes.forEach(function(node){ + block.push(node); + }); + break; + default: + var text = new nodes.Text(indent + this.advance().val); + text.line = this.line(); + block.push(text); + } + } + + if (spaces == this._spaces) this._spaces = null; + this.expect('outdent'); + return block; + }, + + /** + * indent expr* outdent + */ + + block: function(){ + var block = new nodes.Block; + block.line = this.line(); + this.expect('indent'); + while ('outdent' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + this.expect('outdent'); + return block; + }, + + /** + * interpolation (attrs | class | id)* (text | code | ':')? newline* block? + */ + + parseInterpolation: function(){ + var tok = this.advance(); + var tag = new nodes.Tag(tok.val); + tag.buffer = true; + return this.tag(tag); + }, + + /** + * tag (attrs | class | id)* (text | code | ':')? newline* block? + */ + + parseTag: function(){ + // ast-filter look-ahead + var i = 2; + if ('attrs' == this.lookahead(i).type) ++i; + if (':' == this.lookahead(i).type) { + if ('indent' == this.lookahead(++i).type) { + return this.parseASTFilter(); + } + } + + var tok = this.advance() + , tag = new nodes.Tag(tok.val); + + tag.selfClosing = tok.selfClosing; + + return this.tag(tag); + }, + + /** + * Parse tag. + */ + + tag: function(tag){ + var dot; + + tag.line = this.line(); + + // (attrs | class | id)* + out: + while (true) { + switch (this.peek().type) { + case 'id': + case 'class': + var tok = this.advance(); + tag.setAttribute(tok.type, "'" + tok.val + "'"); + continue; + case 'attrs': + var tok = this.advance() + , obj = tok.attrs + , escaped = tok.escaped + , names = Object.keys(obj); + + if (tok.selfClosing) tag.selfClosing = true; + + for (var i = 0, len = names.length; i < len; ++i) { + var name = names[i] + , val = obj[name]; + tag.setAttribute(name, val, escaped[name]); + } + continue; + default: + break out; + } + } + + // check immediate '.' + if ('.' == this.peek().val) { + dot = tag.textOnly = true; + this.advance(); + } + + // (text | code | ':')? + switch (this.peek().type) { + case 'text': + tag.block.push(this.parseText()); + break; + case 'code': + tag.code = this.parseCode(); + break; + case ':': + this.advance(); + tag.block = new nodes.Block; + tag.block.push(this.parseExpr()); + break; + } + + // newline* + while ('newline' == this.peek().type) this.advance(); + + tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name); + + // script special-case + if ('script' == tag.name) { + var type = tag.getAttribute('type'); + if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) { + tag.textOnly = false; + } + } + + // block? + if ('indent' == this.peek().type) { + if (tag.textOnly) { + this.lexer.pipeless = true; + tag.block = this.parseTextBlock(); + this.lexer.pipeless = false; + } else { + var block = this.block(); + if (tag.block) { + for (var i = 0, len = block.nodes.length; i < len; ++i) { + tag.block.push(block.nodes[i]); + } + } else { + tag.block = block; + } + } + } + + return tag; + } +}; + +}); // module: parser.js + +require.register("runtime.js", function(module, exports, require){ + +/*! + * Jade - runtime + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Lame Array.isArray() polyfill for now. + */ + +if (!Array.isArray) { + Array.isArray = function(arr){ + return '[object Array]' == Object.prototype.toString.call(arr); + }; +} + +/** + * Lame Object.keys() polyfill for now. + */ + +if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } +} + +/** + * Merge two attribute objects giving precedence + * to values in object `b`. Classes are special-cased + * allowing for arrays and merging/joining appropriately + * resulting in a string. + * + * @param {Object} a + * @param {Object} b + * @return {Object} a + * @api private + */ + +exports.merge = function merge(a, b) { + var ac = a['class']; + var bc = b['class']; + + if (ac || bc) { + ac = ac || []; + bc = bc || []; + if (!Array.isArray(ac)) ac = [ac]; + if (!Array.isArray(bc)) bc = [bc]; + ac = ac.filter(nulls); + bc = bc.filter(nulls); + a['class'] = ac.concat(bc).join(' '); + } + + for (var key in b) { + if (key != 'class') { + a[key] = b[key]; + } + } + + return a; +}; + +/** + * Filter null `val`s. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function nulls(val) { + return val != null; +} + +/** + * Render the given attributes object. + * + * @param {Object} obj + * @param {Object} escaped + * @return {String} + * @api private + */ + +exports.attrs = function attrs(obj, escaped){ + var buf = [] + , terse = obj.terse; + + delete obj.terse; + var keys = Object.keys(obj) + , len = keys.length; + + if (len) { + buf.push(''); + for (var i = 0; i < len; ++i) { + var key = keys[i] + , val = obj[key]; + + if ('boolean' == typeof val || null == val) { + if (val) { + terse + ? buf.push(key) + : buf.push(key + '="' + key + '"'); + } + } else if (0 == key.indexOf('data') && 'string' != typeof val) { + buf.push(key + "='" + JSON.stringify(val) + "'"); + } else if ('class' == key && Array.isArray(val)) { + buf.push(key + '="' + exports.escape(val.join(' ')) + '"'); + } else if (escaped && escaped[key]) { + buf.push(key + '="' + exports.escape(val) + '"'); + } else { + buf.push(key + '="' + val + '"'); + } + } + } + + return buf.join(' '); +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function escape(html){ + return String(html) + .replace(/&(?!(\w+|\#\d+);)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Re-throw the given `err` in context to the + * the jade in `filename` at the given `lineno`. + * + * @param {Error} err + * @param {String} filename + * @param {String} lineno + * @api private + */ + +exports.rethrow = function rethrow(err, filename, lineno){ + if (!filename) throw err; + + var context = 3 + , str = require('fs').readFileSync(filename, 'utf8') + , lines = str.split('\n') + , start = Math.max(lineno - context, 0) + , end = Math.min(lines.length, lineno + context); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' > ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'Jade') + ':' + lineno + + '\n' + context + '\n\n' + err.message; + throw err; +}; + +}); // module: runtime.js + +require.register("self-closing.js", function(module, exports, require){ + +/*! + * Jade - self closing tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'meta' + , 'img' + , 'link' + , 'input' + , 'source' + , 'area' + , 'base' + , 'col' + , 'br' + , 'hr' +]; +}); // module: self-closing.js + +require.register("utils.js", function(module, exports, require){ + +/*! + * Jade - utils + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Convert interpolation in the given string to JavaScript. + * + * @param {String} str + * @return {String} + * @api private + */ + +var interpolate = exports.interpolate = function(str){ + return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){ + return escape + ? str + : "' + " + + ('!' == flag ? '' : 'escape') + + "((interp = " + code.replace(/\\'/g, "'") + + ") == null ? '' : interp) + '"; + }); +}; + +/** + * Escape single quotes in `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +var escape = exports.escape = function(str) { + return str.replace(/'/g, "\\'"); +}; + +/** + * Interpolate, and escape the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.text = function(str){ + return interpolate(escape(str)); +}; +}); // module: utils.js + +window.jade = require("jade"); +})(); diff --git a/node_modules/mocha/node_modules/jade/jade.md b/node_modules/mocha/node_modules/jade/jade.md new file mode 100644 index 0000000..051dc03 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/jade.md @@ -0,0 +1,510 @@ + +# Jade + + The jade template engine for node.js + +## Synopsis + + jade [-h|--help] [-v|--version] [-o|--obj STR] + [-O|--out DIR] [-p|--path PATH] [-P|--pretty] + [-c|--client] [-D|--no-debug] + +## Examples + + translate jade the templates dir + + $ jade templates + + create {foo,bar}.html + + $ jade {foo,bar}.jade + + jade over stdio + + $ jade < my.jade > my.html + + jade over s + + $ echo "h1 Jade!" | jade + + foo, bar dirs rendering to /tmp + + $ jade foo bar --out /tmp + + compile client-side templates without debugging + instrumentation, making the output javascript + very light-weight. This requires runtime.js + in your projects. + + $ jade --client --no-debug < my.jade + +## Tags + + Tags are simply nested via whitespace, closing + tags defined for you. These indents are called "blocks". + + ul + li + a Foo + li + a Bar + + You may have several tags in one "block": + + ul + li + a Foo + a Bar + a Baz + +## Self-closing Tags + + Some tags are flagged as self-closing by default, such + as `meta`, `link`, and so on. To explicitly self-close + a tag simply append the `/` character: + + foo/ + foo(bar='baz')/ + + Would yield: + + + + +## Attributes + + Tag attributes look similar to HTML, however + the values are regular JavaScript, here are + some examples: + + a(href='google.com') Google + a(class='button', href='google.com') Google + + As mentioned the attribute values are just JavaScript, + this means ternary operations and other JavaScript expressions + work just fine: + + body(class=user.authenticated ? 'authenticated' : 'anonymous') + a(href=user.website || 'http://google.com') + + Multiple lines work too: + + input(type='checkbox', + name='agreement', + checked) + + Multiple lines without the comma work fine: + + input(type='checkbox' + name='agreement' + checked) + + Funky whitespace? fine: + + input( + type='checkbox' + name='agreement' + checked) + +## Boolean attributes + + Boolean attributes are mirrored by Jade, and accept + bools, aka _true_ or _false_. When no value is specified + _true_ is assumed. For example: + + input(type="checkbox", checked) + // => "" + + For example if the checkbox was for an agreement, perhaps `user.agreed` + was _true_ the following would also output 'checked="checked"': + + input(type="checkbox", checked=user.agreed) + +## Class attributes + + The _class_ attribute accepts an array of classes, + this can be handy when generated from a javascript + function etc: + + classes = ['foo', 'bar', 'baz'] + a(class=classes) + // => "" + +## Class literal + + Classes may be defined using a ".CLASSNAME" syntax: + + .button + // => "
    " + + Or chained: + + .large.button + // => "
    " + + The previous defaulted to divs, however you + may also specify the tag type: + + h1.title My Title + // => "

    My Title

    " + +## Id literal + + Much like the class literal there's an id literal: + + #user-1 + // => "
    " + + Again we may specify the tag as well: + + ul#menu + li: a(href='/home') Home + li: a(href='/store') Store + li: a(href='/contact') Contact + + Finally all of these may be used in any combination, + the following are all valid tags: + + a.button#contact(style: 'color: red') Contact + a.button(style: 'color: red')#contact Contact + a(style: 'color: red').button#contact Contact + +## Block expansion + + Jade supports the concept of "block expansion", in which + using a trailing ":" after a tag will inject a block: + + ul + li: a Foo + li: a Bar + li: a Baz + +## Text + + Arbitrary text may follow tags: + + p Welcome to my site + + yields: + +

    Welcome to my site

    + +## Pipe text + + Another form of text is "pipe" text. Pipes act + as the text margin for large bodies of text. + + p + | This is a large + | body of text for + | this tag. + | + | Nothing too + | exciting. + + yields: + +

    This is a large + body of text for + this tag. + + Nothing too + exciting. +

    + + Using pipes we can also specify regular Jade tags + within the text: + + p + | Click to visit + a(href='http://google.com') Google + | if you want. + +## Text only tags + + As an alternative to pipe text you may add + a trailing "." to indicate that the block + contains nothing but plain-text, no tags: + + p. + This is a large + body of text for + this tag. + + Nothing too + exciting. + + Some tags are text-only by default, for example + _script_, _textarea_, and _style_ tags do not + contain nested HTML so Jade implies the trailing ".": + + script + if (foo) { + bar(); + } + + style + body { + padding: 50px; + font: 14px Helvetica; + } + +## Template script tags + + Sometimes it's useful to define HTML in script + tags using Jade, typically for client-side templates. + + To do this simply give the _script_ tag an arbitrary + _type_ attribute such as _text/x-template_: + + script(type='text/template') + h1 Look! + p Jade still works in here! + +## Interpolation + + Both plain-text and piped-text support interpolation, + which comes in two forms, escapes and non-escaped. The + following will output the _user.name_ in the paragraph + but HTML within it will be escaped to prevent XSS attacks: + + p Welcome #{user.name} + + The following syntax is identical however it will _not_ escape + HTML, and should only be used with strings that you trust: + + p Welcome !{user.name} + +## Inline HTML + + Sometimes constructing small inline snippets of HTML + in Jade can be annoying, luckily we can add plain + HTML as well: + + p Welcome #{user.name} + +## Code + + To buffer output with Jade simply use _=_ at the beginning + of a line or after a tag. This method escapes any HTML + present in the string. + + p= user.description + + To buffer output unescaped use the _!=_ variant, but again + be careful of XSS. + + p!= user.description + + The final way to mess with JavaScript code in Jade is the unbuffered + _-_, which can be used for conditionals, defining variables etc: + + - var user = { description: 'foo bar baz' } + #user + - if (user.description) { + h2 Description + p.description= user.description + - } + + When compiled blocks are wrapped in anonymous functions, so the + following is also valid, without braces: + + - var user = { description: 'foo bar baz' } + #user + - if (user.description) + h2 Description + p.description= user.description + + If you really want you could even use `.forEach()` and others: + + - users.forEach(function(user){ + .user + h2= user.name + p User #{user.name} is #{user.age} years old + - }) + + Taking this further Jade provides some syntax for conditionals, + iteration, switch statements etc. Let's look at those next! + +## Assignment + + Jade's first-class assignment is simple, simply use the _=_ + operator and Jade will _var_ it for you. The following are equivalent: + + - var user = { name: 'tobi' } + user = { name: 'tobi' } + +## Conditionals + + Jade's first-class conditional syntax allows for optional + parenthesis, and you may now omit the leading _-_ otherwise + it's identical, still just regular javascript: + + user = { description: 'foo bar baz' } + #user + if user.description + h2 Description + p.description= user.description + + Jade provides the negated version, _unless_ as well, the following + are equivalent: + + - if (!(user.isAnonymous)) + p You're logged in as #{user.name} + + unless user.isAnonymous + p You're logged in as #{user.name} + +## Iteration + + JavaScript's _for_ loops don't look very declarative, so Jade + also provides its own _for_ loop construct, aliased as _each_: + + for user in users + .user + h2= user.name + p user #{user.name} is #{user.age} year old + + As mentioned _each_ is identical: + + each user in users + .user + h2= user.name + + If necessary the index is available as well: + + for user, i in users + .user(class='user-#{i}') + h2= user.name + + Remember, it's just JavaScript: + + ul#letters + for letter in ['a', 'b', 'c'] + li= letter + +## Mixins + + Mixins provide a way to define jade "functions" which "mix in" + their contents when called. This is useful for abstracting + out large fragments of Jade. + + The simplest possible mixin which accepts no arguments might + look like this: + + mixin hello + p Hello + + You use a mixin by placing `+` before the name: + + +hello + + For something a little more dynamic, mixins can take + arguments, the mixin itself is converted to a javascript + function internally: + + mixin hello(user) + p Hello #{user} + + +hello('Tobi') + + Yields: + +

    Hello Tobi

    + + Mixins may optionally take blocks, when a block is passed + its contents becomes the implicit `block` argument. For + example here is a mixin passed a block, and also invoked + without passing a block: + + mixin article(title) + .article + .article-wrapper + h1= title + if block + block + else + p No content provided + + +article('Hello world') + + +article('Hello world') + p This is my + p Amazing article + + yields: + +
    +
    +

    Hello world

    +

    No content provided

    +
    +
    + +
    +
    +

    Hello world

    +

    This is my

    +

    Amazing article

    +
    +
    + + Mixins can even take attributes, just like a tag. When + attributes are passed they become the implicit `attributes` + argument. Individual attributes can be accessed just like + normal object properties: + + mixin centered + .centered(class=attributes.class) + block + + +centered.bold Hello world + + +centered.red + p This is my + p Amazing article + + yields: + +
    Hello world
    +
    +

    This is my

    +

    Amazing article

    +
    + + If you use `attributes` directly, *all* passed attributes + get used: + + mixin link + a.menu(attributes) + block + + +link.highlight(href='#top') Top + +link#sec1.plain(href='#section1') Section 1 + +link#sec2.plain(href='#section2') Section 2 + + yields: + + Top + Section 1 + Section 2 + + If you pass arguments, they must directly follow the mixin: + + mixin list(arr) + if block + .title + block + ul(attributes) + each item in arr + li= item + + +list(['foo', 'bar', 'baz'])(id='myList', class='bold') + + yields: + +
      +
    • foo
    • +
    • bar
    • +
    • baz
    • +
    diff --git a/node_modules/mocha/node_modules/jade/jade.min.js b/node_modules/mocha/node_modules/jade/jade.min.js new file mode 100644 index 0000000..72e4535 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/jade.min.js @@ -0,0 +1,2 @@ +(function(){function require(p){var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');return mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path))),mod.exports}require.modules={},require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if("."!=p.charAt(0))return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i",this.doctype=doctype,this.terse="5"==name||"html"==name,this.xml=0==this.doctype.indexOf("1&&!escape&&block.nodes[0].isText&&block.nodes[1].isText&&this.prettyIndent(1,!0);for(var i=0;i0&&!escape&&block.nodes[i].isText&&block.nodes[i-1].isText&&this.prettyIndent(1,!1),this.visit(block.nodes[i]),block.nodes[i+1]&&block.nodes[i].isText&&block.nodes[i+1].isText&&this.buffer("\\n")},visitDoctype:function(doctype){doctype&&(doctype.val||!this.doctype)&&this.setDoctype(doctype.val||"default"),this.doctype&&this.buffer(this.doctype),this.hasCompiledDoctype=!0},visitMixin:function(mixin){var name=mixin.name.replace(/-/g,"_")+"_mixin",args=mixin.args||"",block=mixin.block,attrs=mixin.attrs,pp=this.pp;if(mixin.call){pp&&this.buf.push("__indent.push('"+Array(this.indents+1).join(" ")+"');");if(block||attrs.length){this.buf.push(name+".call({");if(block){this.buf.push("block: function(){"),this.parentIndents++;var _indents=this.indents;this.indents=0,this.visit(mixin.block),this.indents=_indents,this.parentIndents--,attrs.length?this.buf.push("},"):this.buf.push("}")}if(attrs.length){var val=this.attrs(attrs);val.inherits?this.buf.push("attributes: merge({"+val.buf+"}, attributes), escaped: merge("+val.escaped+", escaped, true)"):this.buf.push("attributes: {"+val.buf+"}, escaped: "+val.escaped)}args?this.buf.push("}, "+args+");"):this.buf.push("});")}else this.buf.push(name+"("+args+");");pp&&this.buf.push("__indent.pop();")}else this.buf.push("var "+name+" = function("+args+"){"),this.buf.push("var block = this.block, attributes = this.attributes || {}, escaped = this.escaped || {};"),this.parentIndents++,this.visit(block),this.parentIndents--,this.buf.push("};")},visitTag:function(tag){this.indents++;var name=tag.name,pp=this.pp;tag.buffer&&(name="' + ("+name+") + '"),this.hasCompiledTag||(!this.hasCompiledDoctype&&"html"==name&&this.visitDoctype(),this.hasCompiledTag=!0),pp&&!tag.isInline()&&this.prettyIndent(0,!0),(~selfClosing.indexOf(name)||tag.selfClosing)&&!this.xml?(this.buffer("<"+name),this.visitAttributes(tag.attrs),this.terse?this.buffer(">"):this.buffer("/>")):(tag.attrs.length?(this.buffer("<"+name),tag.attrs.length&&this.visitAttributes(tag.attrs),this.buffer(">")):this.buffer("<"+name+">"),tag.code&&this.visitCode(tag.code),this.escape="pre"==tag.name,this.visit(tag.block),pp&&!tag.isInline()&&"pre"!=tag.name&&!tag.canInline()&&this.prettyIndent(0,!0),this.buffer("")),this.indents--},visitFilter:function(filter){var fn=filters[filter.name];if(!fn)throw filter.isASTFilter?new Error('unknown ast filter "'+filter.name+':"'):new Error('unknown filter ":'+filter.name+'"');if(filter.isASTFilter)this.buf.push(fn(filter.block,this,filter.attrs));else{var text=filter.block.nodes.map(function(node){return node.val}).join("\n");filter.attrs=filter.attrs||{},filter.attrs.filename=this.options.filename,this.buffer(utils.text(fn(text,filter.attrs)))}},visitText:function(text){text=utils.text(text.val.replace(/\\/g,"\\\\")),this.escape&&(text=escape(text)),this.buffer(text)},visitComment:function(comment){if(!comment.buffer)return;this.pp&&this.prettyIndent(1,!0),this.buffer("")},visitBlockComment:function(comment){if(!comment.buffer)return;0==comment.val.trim().indexOf("if")?(this.buffer("")):(this.buffer(""))},visitCode:function(code){if(code.buffer){var val=code.val.trimLeft();this.buf.push("var __val__ = "+val),val='null == __val__ ? "" : __val__',code.escape&&(val="escape("+val+")"),this.buf.push("buf.push("+val+");")}else this.buf.push(code.val);code.block&&(code.buffer||this.buf.push("{"),this.visit(code.block),code.buffer||this.buf.push("}"))},visitEach:function(each){this.buf.push("// iterate "+each.obj+"\n"+";(function(){\n"+" if ('number' == typeof "+each.obj+".length) {\n"+" for (var "+each.key+" = 0, $$l = "+each.obj+".length; "+each.key+" < $$l; "+each.key+"++) {\n"+" var "+each.val+" = "+each.obj+"["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n } else {\n for (var "+each.key+" in "+each.obj+") {\n"+" if ("+each.obj+".hasOwnProperty("+each.key+")){"+" var "+each.val+" = "+each.obj+"["+each.key+"];\n"),this.visit(each.block),this.buf.push(" }\n"),this.buf.push(" }\n }\n}).call(this);\n")},visitAttributes:function(attrs){var val=this.attrs(attrs);val.inherits?this.buf.push("buf.push(attrs(merge({ "+val.buf+" }, attributes), merge("+val.escaped+", escaped, true)));"):val.constant?(eval("var buf={"+val.buf+"};"),this.buffer(runtime.attrs(buf,JSON.parse(val.escaped)),!0)):this.buf.push("buf.push(attrs({ "+val.buf+" }, "+val.escaped+"));")},attrs:function(attrs){var buf=[],classes=[],escaped={},constant=attrs.every(function(attr){return isConstant(attr.val)}),inherits=!1;return this.terse&&buf.push("terse: true"),attrs.forEach(function(attr){if(attr.name=="attributes")return inherits=!0;escaped[attr.name]=attr.escaped;if(attr.name=="class")classes.push("("+attr.val+")");else{var pair="'"+attr.name+"':("+attr.val+")";buf.push(pair)}}),classes.length&&(classes=classes.join(" + ' ' + "),buf.push("class: "+classes)),{buf:buf.join(", ").replace("class:",'"class":'),escaped:JSON.stringify(escaped),inherits:inherits,constant:constant}}};function isConstant(val){if(/^ *("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|true|false|null|undefined) *$/i.test(val))return!0;if(!isNaN(Number(val)))return!0;var matches;return(matches=/^ *\[(.*)\] *$/.exec(val))?matches[1].split(",").every(isConstant):!1}function escape(html){return String(html).replace(/&(?!\w+;)/g,"&").replace(//g,">").replace(/"/g,""")}}),require.register("doctypes.js",function(module,exports,require){module.exports={5:"","default":"",xml:'',transitional:'',strict:'',frameset:'',1.1:'',basic:'',mobile:''}}),require.register("filters.js",function(module,exports,require){module.exports={cdata:function(str){return""},sass:function(str){str=str.replace(/\\n/g,"\n");var sass=require("sass").render(str).replace(/\n/g,"\\n");return'"},stylus:function(str,options){var ret;str=str.replace(/\\n/g,"\n");var stylus=require("stylus");return stylus(str,options).render(function(err,css){if(err)throw err;ret=css.replace(/\n/g,"\\n")}),'"},less:function(str){var ret;return str=str.replace(/\\n/g,"\n"),require("less").render(str,function(err,css){if(err)throw err;ret='"}),ret},markdown:function(str){var md;try{md=require("markdown")}catch(err){try{md=require("discount")}catch(err){try{md=require("markdown-js")}catch(err){try{md=require("marked")}catch(err){throw new Error("Cannot find markdown library, install markdown, discount, or marked.")}}}}return str=str.replace(/\\n/g,"\n"),md.parse(str).replace(/\n/g,"\\n").replace(/'/g,"'")},coffeescript:function(str){str=str.replace(/\\n/g,"\n");var js=require("coffee-script").compile(str).replace(/\\/g,"\\\\").replace(/\n/g,"\\n");return'"}}}),require.register("inline-tags.js",function(module,exports,require){module.exports=["a","abbr","acronym","b","br","code","em","font","i","img","ins","kbd","map","samp","small","span","strong","sub","sup"]}),require.register("jade.js",function(module,exports,require){var Parser=require("./parser"),Lexer=require("./lexer"),Compiler=require("./compiler"),runtime=require("./runtime");exports.version="0.26.1",exports.selfClosing=require("./self-closing"),exports.doctypes=require("./doctypes"),exports.filters=require("./filters"),exports.utils=require("./utils"),exports.Compiler=Compiler,exports.Parser=Parser,exports.Lexer=Lexer,exports.nodes=require("./nodes"),exports.runtime=runtime,exports.cache={};function parse(str,options){try{var parser=new Parser(str,options.filename,options),compiler=new(options.compiler||Compiler)(parser.parse(),options),js=compiler.compile();return options.debug&&console.error("\nCompiled Function:\n\n%s",js.replace(/^/gm," ")),"var buf = [];\n"+(options.self?"var self = locals || {};\n"+js:"with (locals || {}) {\n"+js+"\n}\n")+'return buf.join("");'}catch(err){parser=parser.context(),runtime.rethrow(err,parser.filename,parser.lexer.lineno)}}exports.compile=function(str,options){var options=options||{},client=options.client,filename=options.filename?JSON.stringify(options.filename):"undefined",fn;return options.compileDebug!==!1?fn=["var __jade = [{ lineno: 1, filename: "+filename+" }];","try {",parse(String(str),options),"} catch (err) {"," rethrow(err, __jade[0].filename, __jade[0].lineno);","}"].join("\n"):fn=parse(String(str),options),client&&(fn="attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;\n"+fn),fn=new Function("locals, attrs, escape, rethrow, merge",fn),client?fn:function(locals){return fn(locals,runtime.attrs,runtime.escape,runtime.rethrow,runtime.merge)}},exports.render=function(str,options,fn){"function"==typeof options&&(fn=options,options={});if(options.cache&&!options.filename)return fn(new Error('the "filename" option is required for caching'));try{var path=options.filename,tmpl=options.cache?exports.cache[path]||(exports.cache[path]=exports.compile(str,options)):exports.compile(str,options);fn(null,tmpl(options))}catch(err){fn(err)}},exports.renderFile=function(path,options,fn){var key=path+":string";"function"==typeof options&&(fn=options,options={});try{options.filename=path;var str=options.cache?exports.cache[key]||(exports.cache[key]=fs.readFileSync(path,"utf8")):fs.readFileSync(path,"utf8");exports.render(str,options,fn)}catch(err){fn(err)}},exports.__express=exports.renderFile}),require.register("lexer.js",function(module,exports,require){var Lexer=module.exports=function Lexer(str,options){options=options||{},this.input=str.replace(/\r\n|\r/g,"\n"),this.colons=options.colons,this.deferredTokens=[],this.lastIndents=0,this.lineno=1,this.stash=[],this.indentStack=[],this.indentRe=null,this.pipeless=!1};Lexer.prototype={tok:function(type,val){return{type:type,line:this.lineno,val:val}},consume:function(len){this.input=this.input.substr(len)},scan:function(regexp,type){var captures;if(captures=regexp.exec(this.input))return this.consume(captures[0].length),this.tok(type,captures[1])},defer:function(tok){this.deferredTokens.push(tok)},lookahead:function(n){var fetch=n-this.stash.length;while(fetch-->0)this.stash.push(this.next());return this.stash[--n]},indexOfDelimiters:function(start,end){var str=this.input,nstart=0,nend=0,pos=0;for(var i=0,len=str.length;iindents)this.stash.push(this.tok("outdent")),this.indentStack.shift();tok=this.stash.pop()}else indents&&indents!=this.indentStack[0]?(this.indentStack.unshift(indents),tok=this.tok("indent",indents)):tok=this.tok("newline");return tok}},pipelessText:function(){if(this.pipeless){if("\n"==this.input[0])return;var i=this.input.indexOf("\n");-1==i&&(i=this.input.length);var str=this.input.substr(0,i);return this.consume(str.length),this.tok("text",str)}},colon:function(){return this.scan(/^: */,":")},advance:function(){return this.stashed()||this.next()},next:function(){return this.deferred()||this.blank()||this.eos()||this.pipelessText()||this.yield()||this.doctype()||this.interpolation()||this["case"]()||this.when()||this["default"]()||this["extends"]()||this.append()||this.prepend()||this.block()||this.include()||this.mixin()||this.call()||this.conditional()||this.each()||this["while"]()||this.assignment()||this.tag()||this.filter()||this.code()||this.id()||this.className()||this.attrs()||this.indent()||this.comment()||this.colon()||this.text()}}}),require.register("nodes/attrs.js",function(module,exports,require){var Node=require("./node"),Block=require("./block"),Attrs=module.exports=function Attrs(){this.attrs=[]};Attrs.prototype=new Node,Attrs.prototype.constructor=Attrs,Attrs.prototype.setAttribute=function(name,val,escaped){return this.attrs.push({name:name,val:val,escaped:escaped}),this},Attrs.prototype.removeAttribute=function(name){for(var i=0,len=this.attrs.length;i/g,">").replace(/"/g,""")},exports.rethrow=function rethrow(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err}}),require.register("self-closing.js",function(module,exports,require){module.exports=["meta","img","link","input","source","area","base","col","br","hr"]}),require.register("utils.js",function(module,exports,require){var interpolate=exports.interpolate=function(str){return str.replace(/(\\)?([#!]){(.*?)}/g,function(str,escape,flag,code){return escape?str:"' + "+("!"==flag?"":"escape")+"((interp = "+code.replace(/\\'/g,"'")+") == null ? '' : interp) + '"})},escape=exports.escape=function(str){return str.replace(/'/g,"\\'")};exports.text=function(str){return interpolate(escape(str))}}),window.jade=require("jade")})(); \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/compiler.js b/node_modules/mocha/node_modules/jade/lib/compiler.js new file mode 100644 index 0000000..516ac83 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/compiler.js @@ -0,0 +1,642 @@ + +/*! + * Jade - Compiler + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var nodes = require('./nodes') + , filters = require('./filters') + , doctypes = require('./doctypes') + , selfClosing = require('./self-closing') + , runtime = require('./runtime') + , utils = require('./utils'); + +// if browser +// +// if (!Object.keys) { +// Object.keys = function(obj){ +// var arr = []; +// for (var key in obj) { +// if (obj.hasOwnProperty(key)) { +// arr.push(key); +// } +// } +// return arr; +// } +// } +// +// if (!String.prototype.trimLeft) { +// String.prototype.trimLeft = function(){ +// return this.replace(/^\s+/, ''); +// } +// } +// +// end + + +/** + * Initialize `Compiler` with the given `node`. + * + * @param {Node} node + * @param {Object} options + * @api public + */ + +var Compiler = module.exports = function Compiler(node, options) { + this.options = options = options || {}; + this.node = node; + this.hasCompiledDoctype = false; + this.hasCompiledTag = false; + this.pp = options.pretty || false; + this.debug = false !== options.compileDebug; + this.indents = 0; + this.parentIndents = 0; + if (options.doctype) this.setDoctype(options.doctype); +}; + +/** + * Compiler prototype. + */ + +Compiler.prototype = { + + /** + * Compile parse tree to JavaScript. + * + * @api public + */ + + compile: function(){ + this.buf = ['var interp;']; + if (this.pp) this.buf.push("var __indent = [];"); + this.lastBufferedIdx = -1; + this.visit(this.node); + return this.buf.join('\n'); + }, + + /** + * Sets the default doctype `name`. Sets terse mode to `true` when + * html 5 is used, causing self-closing tags to end with ">" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {string} name + * @api public + */ + + setDoctype: function(name){ + var doctype = doctypes[(name || 'default').toLowerCase()]; + doctype = doctype || ''; + this.doctype = doctype; + this.terse = '5' == name || 'html' == name; + this.xml = 0 == this.doctype.indexOf(' 1 && !escape && block.nodes[0].isText && block.nodes[1].isText) + this.prettyIndent(1, true); + + for (var i = 0; i < len; ++i) { + // Pretty print text + if (pp && i > 0 && !escape && block.nodes[i].isText && block.nodes[i-1].isText) + this.prettyIndent(1, false); + + this.visit(block.nodes[i]); + // Multiple text nodes are separated by newlines + if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText) + this.buffer('\\n'); + } + }, + + /** + * Visit `doctype`. Sets terse mode to `true` when html 5 + * is used, causing self-closing tags to end with ">" vs "/>", + * and boolean attributes are not mirrored. + * + * @param {Doctype} doctype + * @api public + */ + + visitDoctype: function(doctype){ + if (doctype && (doctype.val || !this.doctype)) { + this.setDoctype(doctype.val || 'default'); + } + + if (this.doctype) this.buffer(this.doctype); + this.hasCompiledDoctype = true; + }, + + /** + * Visit `mixin`, generating a function that + * may be called within the template. + * + * @param {Mixin} mixin + * @api public + */ + + visitMixin: function(mixin){ + var name = mixin.name.replace(/-/g, '_') + '_mixin' + , args = mixin.args || '' + , block = mixin.block + , attrs = mixin.attrs + , pp = this.pp; + + if (mixin.call) { + if (pp) this.buf.push("__indent.push('" + Array(this.indents + 1).join(' ') + "');") + if (block || attrs.length) { + + this.buf.push(name + '.call({'); + + if (block) { + this.buf.push('block: function(){'); + + // Render block with no indents, dynamically added when rendered + this.parentIndents++; + var _indents = this.indents; + this.indents = 0; + this.visit(mixin.block); + this.indents = _indents; + this.parentIndents--; + + if (attrs.length) { + this.buf.push('},'); + } else { + this.buf.push('}'); + } + } + + if (attrs.length) { + var val = this.attrs(attrs); + if (val.inherits) { + this.buf.push('attributes: merge({' + val.buf + + '}, attributes), escaped: merge(' + val.escaped + ', escaped, true)'); + } else { + this.buf.push('attributes: {' + val.buf + '}, escaped: ' + val.escaped); + } + } + + if (args) { + this.buf.push('}, ' + args + ');'); + } else { + this.buf.push('});'); + } + + } else { + this.buf.push(name + '(' + args + ');'); + } + if (pp) this.buf.push("__indent.pop();") + } else { + this.buf.push('var ' + name + ' = function(' + args + '){'); + this.buf.push('var block = this.block, attributes = this.attributes || {}, escaped = this.escaped || {};'); + this.parentIndents++; + this.visit(block); + this.parentIndents--; + this.buf.push('};'); + } + }, + + /** + * Visit `tag` buffering tag markup, generating + * attributes, visiting the `tag`'s code and block. + * + * @param {Tag} tag + * @api public + */ + + visitTag: function(tag){ + this.indents++; + var name = tag.name + , pp = this.pp; + + if (tag.buffer) name = "' + (" + name + ") + '"; + + if (!this.hasCompiledTag) { + if (!this.hasCompiledDoctype && 'html' == name) { + this.visitDoctype(); + } + this.hasCompiledTag = true; + } + + // pretty print + if (pp && !tag.isInline()) + this.prettyIndent(0, true); + + if ((~selfClosing.indexOf(name) || tag.selfClosing) && !this.xml) { + this.buffer('<' + name); + this.visitAttributes(tag.attrs); + this.terse + ? this.buffer('>') + : this.buffer('/>'); + } else { + // Optimize attributes buffering + if (tag.attrs.length) { + this.buffer('<' + name); + if (tag.attrs.length) this.visitAttributes(tag.attrs); + this.buffer('>'); + } else { + this.buffer('<' + name + '>'); + } + if (tag.code) this.visitCode(tag.code); + this.escape = 'pre' == tag.name; + this.visit(tag.block); + + // pretty print + if (pp && !tag.isInline() && 'pre' != tag.name && !tag.canInline()) + this.prettyIndent(0, true); + + this.buffer(''); + } + this.indents--; + }, + + /** + * Visit `filter`, throwing when the filter does not exist. + * + * @param {Filter} filter + * @api public + */ + + visitFilter: function(filter){ + var fn = filters[filter.name]; + + // unknown filter + if (!fn) { + if (filter.isASTFilter) { + throw new Error('unknown ast filter "' + filter.name + ':"'); + } else { + throw new Error('unknown filter ":' + filter.name + '"'); + } + } + + if (filter.isASTFilter) { + this.buf.push(fn(filter.block, this, filter.attrs)); + } else { + var text = filter.block.nodes.map(function(node){ return node.val }).join('\n'); + filter.attrs = filter.attrs || {}; + filter.attrs.filename = this.options.filename; + this.buffer(utils.text(fn(text, filter.attrs))); + } + }, + + /** + * Visit `text` node. + * + * @param {Text} text + * @api public + */ + + visitText: function(text){ + text = utils.text(text.val.replace(/\\/g, '\\\\')); + if (this.escape) text = escape(text); + this.buffer(text); + }, + + /** + * Visit a `comment`, only buffering when the buffer flag is set. + * + * @param {Comment} comment + * @api public + */ + + visitComment: function(comment){ + if (!comment.buffer) return; + if (this.pp) this.prettyIndent(1, true); + this.buffer(''); + }, + + /** + * Visit a `BlockComment`. + * + * @param {Comment} comment + * @api public + */ + + visitBlockComment: function(comment){ + if (!comment.buffer) return; + if (0 == comment.val.trim().indexOf('if')) { + this.buffer(''); + } else { + this.buffer(''); + } + }, + + /** + * Visit `code`, respecting buffer / escape flags. + * If the code is followed by a block, wrap it in + * a self-calling function. + * + * @param {Code} code + * @api public + */ + + visitCode: function(code){ + // Wrap code blocks with {}. + // we only wrap unbuffered code blocks ATM + // since they are usually flow control + + // Buffer code + if (code.buffer) { + var val = code.val.trimLeft(); + this.buf.push('var __val__ = ' + val); + val = 'null == __val__ ? "" : __val__'; + if (code.escape) val = 'escape(' + val + ')'; + this.buf.push("buf.push(" + val + ");"); + } else { + this.buf.push(code.val); + } + + // Block support + if (code.block) { + if (!code.buffer) this.buf.push('{'); + this.visit(code.block); + if (!code.buffer) this.buf.push('}'); + } + }, + + /** + * Visit `each` block. + * + * @param {Each} each + * @api public + */ + + visitEach: function(each){ + this.buf.push('' + + '// iterate ' + each.obj + '\n' + + ';(function(){\n' + + ' if (\'number\' == typeof ' + each.obj + '.length) {\n' + + ' for (var ' + each.key + ' = 0, $$l = ' + each.obj + '.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n' + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + this.buf.push('' + + ' }\n' + + ' } else {\n' + + ' for (var ' + each.key + ' in ' + each.obj + ') {\n' + // if browser + // + ' if (' + each.obj + '.hasOwnProperty(' + each.key + ')){' + // end + + ' var ' + each.val + ' = ' + each.obj + '[' + each.key + '];\n'); + + this.visit(each.block); + + // if browser + // this.buf.push(' }\n'); + // end + + this.buf.push(' }\n }\n}).call(this);\n'); + }, + + /** + * Visit `attrs`. + * + * @param {Array} attrs + * @api public + */ + + visitAttributes: function(attrs){ + var val = this.attrs(attrs); + if (val.inherits) { + this.buf.push("buf.push(attrs(merge({ " + val.buf + + " }, attributes), merge(" + val.escaped + ", escaped, true)));"); + } else if (val.constant) { + eval('var buf={' + val.buf + '};'); + this.buffer(runtime.attrs(buf, JSON.parse(val.escaped)), true); + } else { + this.buf.push("buf.push(attrs({ " + val.buf + " }, " + val.escaped + "));"); + } + }, + + /** + * Compile attributes. + */ + + attrs: function(attrs){ + var buf = [] + , classes = [] + , escaped = {} + , constant = attrs.every(function(attr){ return isConstant(attr.val) }) + , inherits = false; + + if (this.terse) buf.push('terse: true'); + + attrs.forEach(function(attr){ + if (attr.name == 'attributes') return inherits = true; + escaped[attr.name] = attr.escaped; + if (attr.name == 'class') { + classes.push('(' + attr.val + ')'); + } else { + var pair = "'" + attr.name + "':(" + attr.val + ')'; + buf.push(pair); + } + }); + + if (classes.length) { + classes = classes.join(" + ' ' + "); + buf.push("class: " + classes); + } + + return { + buf: buf.join(', ').replace('class:', '"class":'), + escaped: JSON.stringify(escaped), + inherits: inherits, + constant: constant + }; + } +}; + +/** + * Check if expression can be evaluated to a constant + * + * @param {String} expression + * @return {Boolean} + * @api private + */ + +function isConstant(val){ + // Check strings/literals + if (/^ *("([^"\\]*(\\.[^"\\]*)*)"|'([^'\\]*(\\.[^'\\]*)*)'|true|false|null|undefined) *$/i.test(val)) + return true; + + // Check numbers + if (!isNaN(Number(val))) + return true; + + // Check arrays + var matches; + if (matches = /^ *\[(.*)\] *$/.exec(val)) + return matches[1].split(',').every(isConstant); + + return false; +} + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +function escape(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/doctypes.js b/node_modules/mocha/node_modules/jade/lib/doctypes.js new file mode 100644 index 0000000..e87ca1e --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/doctypes.js @@ -0,0 +1,18 @@ + +/*! + * Jade - doctypes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + '5': '' + , 'default': '' + , 'xml': '' + , 'transitional': '' + , 'strict': '' + , 'frameset': '' + , '1.1': '' + , 'basic': '' + , 'mobile': '' +}; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/filters.js b/node_modules/mocha/node_modules/jade/lib/filters.js new file mode 100644 index 0000000..fdb634c --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/filters.js @@ -0,0 +1,97 @@ + +/*! + * Jade - filters + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = { + + /** + * Wrap text with CDATA block. + */ + + cdata: function(str){ + return ''; + }, + + /** + * Transform sass to css, wrapped in style tags. + */ + + sass: function(str){ + str = str.replace(/\\n/g, '\n'); + var sass = require('sass').render(str).replace(/\n/g, '\\n'); + return ''; + }, + + /** + * Transform stylus to css, wrapped in style tags. + */ + + stylus: function(str, options){ + var ret; + str = str.replace(/\\n/g, '\n'); + var stylus = require('stylus'); + stylus(str, options).render(function(err, css){ + if (err) throw err; + ret = css.replace(/\n/g, '\\n'); + }); + return ''; + }, + + /** + * Transform less to css, wrapped in style tags. + */ + + less: function(str){ + var ret; + str = str.replace(/\\n/g, '\n'); + require('less').render(str, function(err, css){ + if (err) throw err; + ret = ''; + }); + return ret; + }, + + /** + * Transform markdown to html. + */ + + markdown: function(str){ + var md; + + // support markdown / discount + try { + md = require('markdown'); + } catch (err){ + try { + md = require('discount'); + } catch (err) { + try { + md = require('markdown-js'); + } catch (err) { + try { + md = require('marked'); + } catch (err) { + throw new + Error('Cannot find markdown library, install markdown, discount, or marked.'); + } + } + } + } + + str = str.replace(/\\n/g, '\n'); + return md.parse(str).replace(/\n/g, '\\n').replace(/'/g,'''); + }, + + /** + * Transform coffeescript to javascript. + */ + + coffeescript: function(str){ + str = str.replace(/\\n/g, '\n'); + var js = require('coffee-script').compile(str).replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); + return ''; + } +}; diff --git a/node_modules/mocha/node_modules/jade/lib/inline-tags.js b/node_modules/mocha/node_modules/jade/lib/inline-tags.js new file mode 100644 index 0000000..491de0b --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/inline-tags.js @@ -0,0 +1,28 @@ + +/*! + * Jade - inline tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'a' + , 'abbr' + , 'acronym' + , 'b' + , 'br' + , 'code' + , 'em' + , 'font' + , 'i' + , 'img' + , 'ins' + , 'kbd' + , 'map' + , 'samp' + , 'small' + , 'span' + , 'strong' + , 'sub' + , 'sup' +]; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/jade.js b/node_modules/mocha/node_modules/jade/lib/jade.js new file mode 100644 index 0000000..00f0abb --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/jade.js @@ -0,0 +1,237 @@ +/*! + * Jade + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Parser = require('./parser') + , Lexer = require('./lexer') + , Compiler = require('./compiler') + , runtime = require('./runtime') +// if node + , fs = require('fs'); +// end + +/** + * Library version. + */ + +exports.version = '0.26.3'; + +/** + * Expose self closing tags. + */ + +exports.selfClosing = require('./self-closing'); + +/** + * Default supported doctypes. + */ + +exports.doctypes = require('./doctypes'); + +/** + * Text filters. + */ + +exports.filters = require('./filters'); + +/** + * Utilities. + */ + +exports.utils = require('./utils'); + +/** + * Expose `Compiler`. + */ + +exports.Compiler = Compiler; + +/** + * Expose `Parser`. + */ + +exports.Parser = Parser; + +/** + * Expose `Lexer`. + */ + +exports.Lexer = Lexer; + +/** + * Nodes. + */ + +exports.nodes = require('./nodes'); + +/** + * Jade runtime helpers. + */ + +exports.runtime = runtime; + +/** + * Template function cache. + */ + +exports.cache = {}; + +/** + * Parse the given `str` of jade and return a function body. + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api private + */ + +function parse(str, options){ + try { + // Parse + var parser = new Parser(str, options.filename, options); + + // Compile + var compiler = new (options.compiler || Compiler)(parser.parse(), options) + , js = compiler.compile(); + + // Debug compiler + if (options.debug) { + console.error('\nCompiled Function:\n\n\033[90m%s\033[0m', js.replace(/^/gm, ' ')); + } + + return '' + + 'var buf = [];\n' + + (options.self + ? 'var self = locals || {};\n' + js + : 'with (locals || {}) {\n' + js + '\n}\n') + + 'return buf.join("");'; + } catch (err) { + parser = parser.context(); + runtime.rethrow(err, parser.filename, parser.lexer.lineno); + } +} + +/** + * Compile a `Function` representation of the given jade `str`. + * + * Options: + * + * - `compileDebug` when `false` debugging code is stripped from the compiled template + * - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()` + * for use with the Jade client-side runtime.js + * + * @param {String} str + * @param {Options} options + * @return {Function} + * @api public + */ + +exports.compile = function(str, options){ + var options = options || {} + , client = options.client + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined' + , fn; + + if (options.compileDebug !== false) { + fn = [ + 'var __jade = [{ lineno: 1, filename: ' + filename + ' }];' + , 'try {' + , parse(String(str), options) + , '} catch (err) {' + , ' rethrow(err, __jade[0].filename, __jade[0].lineno);' + , '}' + ].join('\n'); + } else { + fn = parse(String(str), options); + } + + if (client) { + fn = 'attrs = attrs || jade.attrs; escape = escape || jade.escape; rethrow = rethrow || jade.rethrow; merge = merge || jade.merge;\n' + fn; + } + + fn = new Function('locals, attrs, escape, rethrow, merge', fn); + + if (client) return fn; + + return function(locals){ + return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow, runtime.merge); + }; +}; + +/** + * Render the given `str` of jade and invoke + * the callback `fn(err, str)`. + * + * Options: + * + * - `cache` enable template caching + * - `filename` filename required for `include` / `extends` and caching + * + * @param {String} str + * @param {Object|Function} options or fn + * @param {Function} fn + * @api public + */ + +exports.render = function(str, options, fn){ + // swap args + if ('function' == typeof options) { + fn = options, options = {}; + } + + // cache requires .filename + if (options.cache && !options.filename) { + return fn(new Error('the "filename" option is required for caching')); + } + + try { + var path = options.filename; + var tmpl = options.cache + ? exports.cache[path] || (exports.cache[path] = exports.compile(str, options)) + : exports.compile(str, options); + fn(null, tmpl(options)); + } catch (err) { + fn(err); + } +}; + +/** + * Render a Jade file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + try { + options.filename = path; + var str = options.cache + ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + exports.render(str, options, fn); + } catch (err) { + fn(err); + } +}; + +/** + * Express support. + */ + +exports.__express = exports.renderFile; diff --git a/node_modules/mocha/node_modules/jade/lib/lexer.js b/node_modules/mocha/node_modules/jade/lib/lexer.js new file mode 100644 index 0000000..bca314a --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/lexer.js @@ -0,0 +1,771 @@ + +/*! + * Jade - Lexer + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize `Lexer` with the given `str`. + * + * Options: + * + * - `colons` allow colons for attr delimiters + * + * @param {String} str + * @param {Object} options + * @api private + */ + +var Lexer = module.exports = function Lexer(str, options) { + options = options || {}; + this.input = str.replace(/\r\n|\r/g, '\n'); + this.colons = options.colons; + this.deferredTokens = []; + this.lastIndents = 0; + this.lineno = 1; + this.stash = []; + this.indentStack = []; + this.indentRe = null; + this.pipeless = false; +}; + +/** + * Lexer prototype. + */ + +Lexer.prototype = { + + /** + * Construct a token with the given `type` and `val`. + * + * @param {String} type + * @param {String} val + * @return {Object} + * @api private + */ + + tok: function(type, val){ + return { + type: type + , line: this.lineno + , val: val + } + }, + + /** + * Consume the given `len` of input. + * + * @param {Number} len + * @api private + */ + + consume: function(len){ + this.input = this.input.substr(len); + }, + + /** + * Scan for `type` with the given `regexp`. + * + * @param {String} type + * @param {RegExp} regexp + * @return {Object} + * @api private + */ + + scan: function(regexp, type){ + var captures; + if (captures = regexp.exec(this.input)) { + this.consume(captures[0].length); + return this.tok(type, captures[1]); + } + }, + + /** + * Defer the given `tok`. + * + * @param {Object} tok + * @api private + */ + + defer: function(tok){ + this.deferredTokens.push(tok); + }, + + /** + * Lookahead `n` tokens. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + var fetch = n - this.stash.length; + while (fetch-- > 0) this.stash.push(this.next()); + return this.stash[--n]; + }, + + /** + * Return the indexOf `start` / `end` delimiters. + * + * @param {String} start + * @param {String} end + * @return {Number} + * @api private + */ + + indexOfDelimiters: function(start, end){ + var str = this.input + , nstart = 0 + , nend = 0 + , pos = 0; + for (var i = 0, len = str.length; i < len; ++i) { + if (start == str.charAt(i)) { + ++nstart; + } else if (end == str.charAt(i)) { + if (++nend == nstart) { + pos = i; + break; + } + } + } + return pos; + }, + + /** + * Stashed token. + */ + + stashed: function() { + return this.stash.length + && this.stash.shift(); + }, + + /** + * Deferred token. + */ + + deferred: function() { + return this.deferredTokens.length + && this.deferredTokens.shift(); + }, + + /** + * end-of-source. + */ + + eos: function() { + if (this.input.length) return; + if (this.indentStack.length) { + this.indentStack.shift(); + return this.tok('outdent'); + } else { + return this.tok('eos'); + } + }, + + /** + * Blank line. + */ + + blank: function() { + var captures; + if (captures = /^\n *\n/.exec(this.input)) { + this.consume(captures[0].length - 1); + if (this.pipeless) return this.tok('text', ''); + return this.next(); + } + }, + + /** + * Comment. + */ + + comment: function() { + var captures; + if (captures = /^ *\/\/(-)?([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('comment', captures[2]); + tok.buffer = '-' != captures[1]; + return tok; + } + }, + + /** + * Interpolated tag. + */ + + interpolation: function() { + var captures; + if (captures = /^#\{(.*?)\}/.exec(this.input)) { + this.consume(captures[0].length); + return this.tok('interpolation', captures[1]); + } + }, + + /** + * Tag. + */ + + tag: function() { + var captures; + if (captures = /^(\w[-:\w]*)(\/?)/.exec(this.input)) { + this.consume(captures[0].length); + var tok, name = captures[1]; + if (':' == name[name.length - 1]) { + name = name.slice(0, -1); + tok = this.tok('tag', name); + this.defer(this.tok(':')); + while (' ' == this.input[0]) this.input = this.input.substr(1); + } else { + tok = this.tok('tag', name); + } + tok.selfClosing = !! captures[2]; + return tok; + } + }, + + /** + * Filter. + */ + + filter: function() { + return this.scan(/^:(\w+)/, 'filter'); + }, + + /** + * Doctype. + */ + + doctype: function() { + return this.scan(/^(?:!!!|doctype) *([^\n]+)?/, 'doctype'); + }, + + /** + * Id. + */ + + id: function() { + return this.scan(/^#([\w-]+)/, 'id'); + }, + + /** + * Class. + */ + + className: function() { + return this.scan(/^\.([\w-]+)/, 'class'); + }, + + /** + * Text. + */ + + text: function() { + return this.scan(/^(?:\| ?| ?)?([^\n]+)/, 'text'); + }, + + /** + * Extends. + */ + + "extends": function() { + return this.scan(/^extends? +([^\n]+)/, 'extends'); + }, + + /** + * Block prepend. + */ + + prepend: function() { + var captures; + if (captures = /^prepend +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var mode = 'prepend' + , name = captures[1] + , tok = this.tok('block', name); + tok.mode = mode; + return tok; + } + }, + + /** + * Block append. + */ + + append: function() { + var captures; + if (captures = /^append +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var mode = 'append' + , name = captures[1] + , tok = this.tok('block', name); + tok.mode = mode; + return tok; + } + }, + + /** + * Block. + */ + + block: function() { + var captures; + if (captures = /^block\b *(?:(prepend|append) +)?([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var mode = captures[1] || 'replace' + , name = captures[2] + , tok = this.tok('block', name); + + tok.mode = mode; + return tok; + } + }, + + /** + * Yield. + */ + + yield: function() { + return this.scan(/^yield */, 'yield'); + }, + + /** + * Include. + */ + + include: function() { + return this.scan(/^include +([^\n]+)/, 'include'); + }, + + /** + * Case. + */ + + "case": function() { + return this.scan(/^case +([^\n]+)/, 'case'); + }, + + /** + * When. + */ + + when: function() { + return this.scan(/^when +([^:\n]+)/, 'when'); + }, + + /** + * Default. + */ + + "default": function() { + return this.scan(/^default */, 'default'); + }, + + /** + * Assignment. + */ + + assignment: function() { + var captures; + if (captures = /^(\w+) += *([^;\n]+)( *;? *)/.exec(this.input)) { + this.consume(captures[0].length); + var name = captures[1] + , val = captures[2]; + return this.tok('code', 'var ' + name + ' = (' + val + ');'); + } + }, + + /** + * Call mixin. + */ + + call: function(){ + var captures; + if (captures = /^\+([-\w]+)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('call', captures[1]); + + // Check for args (not attributes) + if (captures = /^ *\((.*?)\)/.exec(this.input)) { + if (!/^ *[-\w]+ *=/.test(captures[1])) { + this.consume(captures[0].length); + tok.args = captures[1]; + } + } + + return tok; + } + }, + + /** + * Mixin. + */ + + mixin: function(){ + var captures; + if (captures = /^mixin +([-\w]+)(?: *\((.*)\))?/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('mixin', captures[1]); + tok.args = captures[2]; + return tok; + } + }, + + /** + * Conditional. + */ + + conditional: function() { + var captures; + if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) { + this.consume(captures[0].length); + var type = captures[1] + , js = captures[2]; + + switch (type) { + case 'if': js = 'if (' + js + ')'; break; + case 'unless': js = 'if (!(' + js + '))'; break; + case 'else if': js = 'else if (' + js + ')'; break; + case 'else': js = 'else'; break; + } + + return this.tok('code', js); + } + }, + + /** + * While. + */ + + "while": function() { + var captures; + if (captures = /^while +([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + return this.tok('code', 'while (' + captures[1] + ')'); + } + }, + + /** + * Each. + */ + + each: function() { + var captures; + if (captures = /^(?:- *)?(?:each|for) +(\w+)(?: *, *(\w+))? * in *([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var tok = this.tok('each', captures[1]); + tok.key = captures[2] || '$index'; + tok.code = captures[3]; + return tok; + } + }, + + /** + * Code. + */ + + code: function() { + var captures; + if (captures = /^(!?=|-)([^\n]+)/.exec(this.input)) { + this.consume(captures[0].length); + var flags = captures[1]; + captures[1] = captures[2]; + var tok = this.tok('code', captures[1]); + tok.escape = flags[0] === '='; + tok.buffer = flags[0] === '=' || flags[1] === '='; + return tok; + } + }, + + /** + * Attributes. + */ + + attrs: function() { + if ('(' == this.input.charAt(0)) { + var index = this.indexOfDelimiters('(', ')') + , str = this.input.substr(1, index-1) + , tok = this.tok('attrs') + , len = str.length + , colons = this.colons + , states = ['key'] + , escapedAttr + , key = '' + , val = '' + , quote + , c + , p; + + function state(){ + return states[states.length - 1]; + } + + function interpolate(attr) { + return attr.replace(/#\{([^}]+)\}/g, function(_, expr){ + return quote + " + (" + expr + ") + " + quote; + }); + } + + this.consume(index + 1); + tok.attrs = {}; + tok.escaped = {}; + + function parse(c) { + var real = c; + // TODO: remove when people fix ":" + if (colons && ':' == c) c = '='; + switch (c) { + case ',': + case '\n': + switch (state()) { + case 'expr': + case 'array': + case 'string': + case 'object': + val += c; + break; + default: + states.push('key'); + val = val.trim(); + key = key.trim(); + if ('' == key) return; + key = key.replace(/^['"]|['"]$/g, '').replace('!', ''); + tok.escaped[key] = escapedAttr; + tok.attrs[key] = '' == val + ? true + : interpolate(val); + key = val = ''; + } + break; + case '=': + switch (state()) { + case 'key char': + key += real; + break; + case 'val': + case 'expr': + case 'array': + case 'string': + case 'object': + val += real; + break; + default: + escapedAttr = '!' != p; + states.push('val'); + } + break; + case '(': + if ('val' == state() + || 'expr' == state()) states.push('expr'); + val += c; + break; + case ')': + if ('expr' == state() + || 'val' == state()) states.pop(); + val += c; + break; + case '{': + if ('val' == state()) states.push('object'); + val += c; + break; + case '}': + if ('object' == state()) states.pop(); + val += c; + break; + case '[': + if ('val' == state()) states.push('array'); + val += c; + break; + case ']': + if ('array' == state()) states.pop(); + val += c; + break; + case '"': + case "'": + switch (state()) { + case 'key': + states.push('key char'); + break; + case 'key char': + states.pop(); + break; + case 'string': + if (c == quote) states.pop(); + val += c; + break; + default: + states.push('string'); + val += c; + quote = c; + } + break; + case '': + break; + default: + switch (state()) { + case 'key': + case 'key char': + key += c; + break; + default: + val += c; + } + } + p = c; + } + + for (var i = 0; i < len; ++i) { + parse(str.charAt(i)); + } + + parse(','); + + if ('/' == this.input.charAt(0)) { + this.consume(1); + tok.selfClosing = true; + } + + return tok; + } + }, + + /** + * Indent | Outdent | Newline. + */ + + indent: function() { + var captures, re; + + // established regexp + if (this.indentRe) { + captures = this.indentRe.exec(this.input); + // determine regexp + } else { + // tabs + re = /^\n(\t*) */; + captures = re.exec(this.input); + + // spaces + if (captures && !captures[1].length) { + re = /^\n( *)/; + captures = re.exec(this.input); + } + + // established + if (captures && captures[1].length) this.indentRe = re; + } + + if (captures) { + var tok + , indents = captures[1].length; + + ++this.lineno; + this.consume(indents + 1); + + if (' ' == this.input[0] || '\t' == this.input[0]) { + throw new Error('Invalid indentation, you can use tabs or spaces but not both'); + } + + // blank line + if ('\n' == this.input[0]) return this.tok('newline'); + + // outdent + if (this.indentStack.length && indents < this.indentStack[0]) { + while (this.indentStack.length && this.indentStack[0] > indents) { + this.stash.push(this.tok('outdent')); + this.indentStack.shift(); + } + tok = this.stash.pop(); + // indent + } else if (indents && indents != this.indentStack[0]) { + this.indentStack.unshift(indents); + tok = this.tok('indent', indents); + // newline + } else { + tok = this.tok('newline'); + } + + return tok; + } + }, + + /** + * Pipe-less text consumed only when + * pipeless is true; + */ + + pipelessText: function() { + if (this.pipeless) { + if ('\n' == this.input[0]) return; + var i = this.input.indexOf('\n'); + if (-1 == i) i = this.input.length; + var str = this.input.substr(0, i); + this.consume(str.length); + return this.tok('text', str); + } + }, + + /** + * ':' + */ + + colon: function() { + return this.scan(/^: */, ':'); + }, + + /** + * Return the next token object, or those + * previously stashed by lookahead. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.stashed() + || this.next(); + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + next: function() { + return this.deferred() + || this.blank() + || this.eos() + || this.pipelessText() + || this.yield() + || this.doctype() + || this.interpolation() + || this["case"]() + || this.when() + || this["default"]() + || this["extends"]() + || this.append() + || this.prepend() + || this.block() + || this.include() + || this.mixin() + || this.call() + || this.conditional() + || this.each() + || this["while"]() + || this.assignment() + || this.tag() + || this.filter() + || this.code() + || this.id() + || this.className() + || this.attrs() + || this.indent() + || this.comment() + || this.colon() + || this.text(); + } +}; diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/attrs.js b/node_modules/mocha/node_modules/jade/lib/nodes/attrs.js new file mode 100644 index 0000000..5de9b59 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/attrs.js @@ -0,0 +1,77 @@ + +/*! + * Jade - nodes - Attrs + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'), + Block = require('./block'); + +/** + * Initialize a `Attrs` node. + * + * @api public + */ + +var Attrs = module.exports = function Attrs() { + this.attrs = []; +}; + +/** + * Inherit from `Node`. + */ + +Attrs.prototype.__proto__ = Node.prototype; + +/** + * Set attribute `name` to `val`, keep in mind these become + * part of a raw js object literal, so to quote a value you must + * '"quote me"', otherwise or example 'user.name' is literal JavaScript. + * + * @param {String} name + * @param {String} val + * @param {Boolean} escaped + * @return {Tag} for chaining + * @api public + */ + +Attrs.prototype.setAttribute = function(name, val, escaped){ + this.attrs.push({ name: name, val: val, escaped: escaped }); + return this; +}; + +/** + * Remove attribute `name` when present. + * + * @param {String} name + * @api public + */ + +Attrs.prototype.removeAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + delete this.attrs[i]; + } + } +}; + +/** + * Get attribute value by `name`. + * + * @param {String} name + * @return {String} + * @api public + */ + +Attrs.prototype.getAttribute = function(name){ + for (var i = 0, len = this.attrs.length; i < len; ++i) { + if (this.attrs[i] && this.attrs[i].name == name) { + return this.attrs[i].val; + } + } +}; diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js b/node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js new file mode 100644 index 0000000..4f41e4a --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/block-comment.js @@ -0,0 +1,33 @@ + +/*! + * Jade - nodes - BlockComment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `BlockComment` with the given `block`. + * + * @param {String} val + * @param {Block} block + * @param {Boolean} buffer + * @api public + */ + +var BlockComment = module.exports = function BlockComment(val, block, buffer) { + this.block = block; + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +BlockComment.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/block.js b/node_modules/mocha/node_modules/jade/lib/nodes/block.js new file mode 100644 index 0000000..bb00a1d --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/block.js @@ -0,0 +1,121 @@ + +/*! + * Jade - nodes - Block + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Block` with an optional `node`. + * + * @param {Node} node + * @api public + */ + +var Block = module.exports = function Block(node){ + this.nodes = []; + if (node) this.push(node); +}; + +/** + * Inherit from `Node`. + */ + +Block.prototype.__proto__ = Node.prototype; + +/** + * Block flag. + */ + +Block.prototype.isBlock = true; + +/** + * Replace the nodes in `other` with the nodes + * in `this` block. + * + * @param {Block} other + * @api private + */ + +Block.prototype.replace = function(other){ + other.nodes = this.nodes; +}; + +/** + * Pust the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.push = function(node){ + return this.nodes.push(node); +}; + +/** + * Check if this block is empty. + * + * @return {Boolean} + * @api public + */ + +Block.prototype.isEmpty = function(){ + return 0 == this.nodes.length; +}; + +/** + * Unshift the given `node`. + * + * @param {Node} node + * @return {Number} + * @api public + */ + +Block.prototype.unshift = function(node){ + return this.nodes.unshift(node); +}; + +/** + * Return the "last" block, or the first `yield` node. + * + * @return {Block} + * @api private + */ + +Block.prototype.includeBlock = function(){ + var ret = this + , node; + + for (var i = 0, len = this.nodes.length; i < len; ++i) { + node = this.nodes[i]; + if (node.yield) return node; + else if (node.textOnly) continue; + else if (node.includeBlock) ret = node.includeBlock(); + else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock(); + } + + return ret; +}; + +/** + * Return a clone of this block. + * + * @return {Block} + * @api private + */ + +Block.prototype.clone = function(){ + var clone = new Block; + for (var i = 0, len = this.nodes.length; i < len; ++i) { + clone.push(this.nodes[i].clone()); + } + return clone; +}; + diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/case.js b/node_modules/mocha/node_modules/jade/lib/nodes/case.js new file mode 100644 index 0000000..08ff033 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/case.js @@ -0,0 +1,43 @@ + +/*! + * Jade - nodes - Case + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a new `Case` with `expr`. + * + * @param {String} expr + * @api public + */ + +var Case = exports = module.exports = function Case(expr, block){ + this.expr = expr; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Case.prototype.__proto__ = Node.prototype; + +var When = exports.When = function When(expr, block){ + this.expr = expr; + this.block = block; + this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +When.prototype.__proto__ = Node.prototype; + diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/code.js b/node_modules/mocha/node_modules/jade/lib/nodes/code.js new file mode 100644 index 0000000..babc675 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/code.js @@ -0,0 +1,35 @@ + +/*! + * Jade - nodes - Code + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Code` node with the given code `val`. + * Code may also be optionally buffered and escaped. + * + * @param {String} val + * @param {Boolean} buffer + * @param {Boolean} escape + * @api public + */ + +var Code = module.exports = function Code(val, buffer, escape) { + this.val = val; + this.buffer = buffer; + this.escape = escape; + if (val.match(/^ *else/)) this.debug = false; +}; + +/** + * Inherit from `Node`. + */ + +Code.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/comment.js b/node_modules/mocha/node_modules/jade/lib/nodes/comment.js new file mode 100644 index 0000000..2e1469e --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/comment.js @@ -0,0 +1,32 @@ + +/*! + * Jade - nodes - Comment + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Comment` with the given `val`, optionally `buffer`, + * otherwise the comment may render in the output. + * + * @param {String} val + * @param {Boolean} buffer + * @api public + */ + +var Comment = module.exports = function Comment(val, buffer) { + this.val = val; + this.buffer = buffer; +}; + +/** + * Inherit from `Node`. + */ + +Comment.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/doctype.js b/node_modules/mocha/node_modules/jade/lib/nodes/doctype.js new file mode 100644 index 0000000..b8f33e5 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/doctype.js @@ -0,0 +1,29 @@ + +/*! + * Jade - nodes - Doctype + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Doctype` with the given `val`. + * + * @param {String} val + * @api public + */ + +var Doctype = module.exports = function Doctype(val) { + this.val = val; +}; + +/** + * Inherit from `Node`. + */ + +Doctype.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/each.js b/node_modules/mocha/node_modules/jade/lib/nodes/each.js new file mode 100644 index 0000000..f54101f --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/each.js @@ -0,0 +1,35 @@ + +/*! + * Jade - nodes - Each + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize an `Each` node, representing iteration + * + * @param {String} obj + * @param {String} val + * @param {String} key + * @param {Block} block + * @api public + */ + +var Each = module.exports = function Each(obj, val, key, block) { + this.obj = obj; + this.val = val; + this.key = key; + this.block = block; +}; + +/** + * Inherit from `Node`. + */ + +Each.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/filter.js b/node_modules/mocha/node_modules/jade/lib/nodes/filter.js new file mode 100644 index 0000000..851a004 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/filter.js @@ -0,0 +1,35 @@ + +/*! + * Jade - nodes - Filter + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node') + , Block = require('./block'); + +/** + * Initialize a `Filter` node with the given + * filter `name` and `block`. + * + * @param {String} name + * @param {Block|Node} block + * @api public + */ + +var Filter = module.exports = function Filter(name, block, attrs) { + this.name = name; + this.block = block; + this.attrs = attrs; + this.isASTFilter = !block.nodes.every(function(node){ return node.isText }); +}; + +/** + * Inherit from `Node`. + */ + +Filter.prototype.__proto__ = Node.prototype; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/index.js b/node_modules/mocha/node_modules/jade/lib/nodes/index.js new file mode 100644 index 0000000..386ad2f --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/index.js @@ -0,0 +1,20 @@ + +/*! + * Jade - nodes + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +exports.Node = require('./node'); +exports.Tag = require('./tag'); +exports.Code = require('./code'); +exports.Each = require('./each'); +exports.Case = require('./case'); +exports.Text = require('./text'); +exports.Block = require('./block'); +exports.Mixin = require('./mixin'); +exports.Filter = require('./filter'); +exports.Comment = require('./comment'); +exports.Literal = require('./literal'); +exports.BlockComment = require('./block-comment'); +exports.Doctype = require('./doctype'); diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/literal.js b/node_modules/mocha/node_modules/jade/lib/nodes/literal.js new file mode 100644 index 0000000..fde586b --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/literal.js @@ -0,0 +1,32 @@ + +/*! + * Jade - nodes - Literal + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Literal` node with the given `str. + * + * @param {String} str + * @api public + */ + +var Literal = module.exports = function Literal(str) { + this.str = str + .replace(/\\/g, "\\\\") + .replace(/\n|\r\n/g, "\\n") + .replace(/'/g, "\\'"); +}; + +/** + * Inherit from `Node`. + */ + +Literal.prototype.__proto__ = Node.prototype; diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/mixin.js b/node_modules/mocha/node_modules/jade/lib/nodes/mixin.js new file mode 100644 index 0000000..8407bc7 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/mixin.js @@ -0,0 +1,36 @@ + +/*! + * Jade - nodes - Mixin + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Attrs = require('./attrs'); + +/** + * Initialize a new `Mixin` with `name` and `block`. + * + * @param {String} name + * @param {String} args + * @param {Block} block + * @api public + */ + +var Mixin = module.exports = function Mixin(name, args, block, call){ + this.name = name; + this.args = args; + this.block = block; + this.attrs = []; + this.call = call; +}; + +/** + * Inherit from `Attrs`. + */ + +Mixin.prototype.__proto__ = Attrs.prototype; + diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/node.js b/node_modules/mocha/node_modules/jade/lib/nodes/node.js new file mode 100644 index 0000000..e98f042 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/node.js @@ -0,0 +1,25 @@ + +/*! + * Jade - nodes - Node + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Initialize a `Node`. + * + * @api public + */ + +var Node = module.exports = function Node(){}; + +/** + * Clone this node (return itself) + * + * @return {Node} + * @api private + */ + +Node.prototype.clone = function(){ + return this; +}; diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/tag.js b/node_modules/mocha/node_modules/jade/lib/nodes/tag.js new file mode 100644 index 0000000..4b6728a --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/tag.js @@ -0,0 +1,95 @@ + +/*! + * Jade - nodes - Tag + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Attrs = require('./attrs'), + Block = require('./block'), + inlineTags = require('../inline-tags'); + +/** + * Initialize a `Tag` node with the given tag `name` and optional `block`. + * + * @param {String} name + * @param {Block} block + * @api public + */ + +var Tag = module.exports = function Tag(name, block) { + this.name = name; + this.attrs = []; + this.block = block || new Block; +}; + +/** + * Inherit from `Attrs`. + */ + +Tag.prototype.__proto__ = Attrs.prototype; + +/** + * Clone this tag. + * + * @return {Tag} + * @api private + */ + +Tag.prototype.clone = function(){ + var clone = new Tag(this.name, this.block.clone()); + clone.line = this.line; + clone.attrs = this.attrs; + clone.textOnly = this.textOnly; + return clone; +}; + +/** + * Check if this tag is an inline tag. + * + * @return {Boolean} + * @api private + */ + +Tag.prototype.isInline = function(){ + return ~inlineTags.indexOf(this.name); +}; + +/** + * Check if this tag's contents can be inlined. Used for pretty printing. + * + * @return {Boolean} + * @api private + */ + +Tag.prototype.canInline = function(){ + var nodes = this.block.nodes; + + function isInline(node){ + // Recurse if the node is a block + if (node.isBlock) return node.nodes.every(isInline); + return node.isText || (node.isInline && node.isInline()); + } + + // Empty tag + if (!nodes.length) return true; + + // Text-only or inline-only tag + if (1 == nodes.length) return isInline(nodes[0]); + + // Multi-line inline-only tag + if (this.block.nodes.every(isInline)) { + for (var i = 1, len = nodes.length; i < len; ++i) { + if (nodes[i-1].isText && nodes[i].isText) + return false; + } + return true; + } + + // Mixed tag + return false; +}; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/nodes/text.js b/node_modules/mocha/node_modules/jade/lib/nodes/text.js new file mode 100644 index 0000000..3b5dd55 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/nodes/text.js @@ -0,0 +1,36 @@ + +/*! + * Jade - nodes - Text + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Node = require('./node'); + +/** + * Initialize a `Text` node with optional `line`. + * + * @param {String} line + * @api public + */ + +var Text = module.exports = function Text(line) { + this.val = ''; + if ('string' == typeof line) this.val = line; +}; + +/** + * Inherit from `Node`. + */ + +Text.prototype.__proto__ = Node.prototype; + +/** + * Flag as text. + */ + +Text.prototype.isText = true; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/parser.js b/node_modules/mocha/node_modules/jade/lib/parser.js new file mode 100644 index 0000000..92f2af0 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/parser.js @@ -0,0 +1,710 @@ + +/*! + * Jade - Parser + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Lexer = require('./lexer') + , nodes = require('./nodes'); + +/** + * Initialize `Parser` with the given input `str` and `filename`. + * + * @param {String} str + * @param {String} filename + * @param {Object} options + * @api public + */ + +var Parser = exports = module.exports = function Parser(str, filename, options){ + this.input = str; + this.lexer = new Lexer(str, options); + this.filename = filename; + this.blocks = {}; + this.mixins = {}; + this.options = options; + this.contexts = [this]; +}; + +/** + * Tags that may not contain tags. + */ + +var textOnly = exports.textOnly = ['script', 'style']; + +/** + * Parser prototype. + */ + +Parser.prototype = { + + /** + * Push `parser` onto the context stack, + * or pop and return a `Parser`. + */ + + context: function(parser){ + if (parser) { + this.contexts.push(parser); + } else { + return this.contexts.pop(); + } + }, + + /** + * Return the next token object. + * + * @return {Object} + * @api private + */ + + advance: function(){ + return this.lexer.advance(); + }, + + /** + * Skip `n` tokens. + * + * @param {Number} n + * @api private + */ + + skip: function(n){ + while (n--) this.advance(); + }, + + /** + * Single token lookahead. + * + * @return {Object} + * @api private + */ + + peek: function() { + return this.lookahead(1); + }, + + /** + * Return lexer lineno. + * + * @return {Number} + * @api private + */ + + line: function() { + return this.lexer.lineno; + }, + + /** + * `n` token lookahead. + * + * @param {Number} n + * @return {Object} + * @api private + */ + + lookahead: function(n){ + return this.lexer.lookahead(n); + }, + + /** + * Parse input returning a string of js for evaluation. + * + * @return {String} + * @api public + */ + + parse: function(){ + var block = new nodes.Block, parser; + block.line = this.line(); + + while ('eos' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + + if (parser = this.extending) { + this.context(parser); + var ast = parser.parse(); + this.context(); + // hoist mixins + for (var name in this.mixins) + ast.unshift(this.mixins[name]); + return ast; + } + + return block; + }, + + /** + * Expect the given type, or throw an exception. + * + * @param {String} type + * @api private + */ + + expect: function(type){ + if (this.peek().type === type) { + return this.advance(); + } else { + throw new Error('expected "' + type + '", but got "' + this.peek().type + '"'); + } + }, + + /** + * Accept the given `type`. + * + * @param {String} type + * @api private + */ + + accept: function(type){ + if (this.peek().type === type) { + return this.advance(); + } + }, + + /** + * tag + * | doctype + * | mixin + * | include + * | filter + * | comment + * | text + * | each + * | code + * | yield + * | id + * | class + * | interpolation + */ + + parseExpr: function(){ + switch (this.peek().type) { + case 'tag': + return this.parseTag(); + case 'mixin': + return this.parseMixin(); + case 'block': + return this.parseBlock(); + case 'case': + return this.parseCase(); + case 'when': + return this.parseWhen(); + case 'default': + return this.parseDefault(); + case 'extends': + return this.parseExtends(); + case 'include': + return this.parseInclude(); + case 'doctype': + return this.parseDoctype(); + case 'filter': + return this.parseFilter(); + case 'comment': + return this.parseComment(); + case 'text': + return this.parseText(); + case 'each': + return this.parseEach(); + case 'code': + return this.parseCode(); + case 'call': + return this.parseCall(); + case 'interpolation': + return this.parseInterpolation(); + case 'yield': + this.advance(); + var block = new nodes.Block; + block.yield = true; + return block; + case 'id': + case 'class': + var tok = this.advance(); + this.lexer.defer(this.lexer.tok('tag', 'div')); + this.lexer.defer(tok); + return this.parseExpr(); + default: + throw new Error('unexpected token "' + this.peek().type + '"'); + } + }, + + /** + * Text + */ + + parseText: function(){ + var tok = this.expect('text') + , node = new nodes.Text(tok.val); + node.line = this.line(); + return node; + }, + + /** + * ':' expr + * | block + */ + + parseBlockExpansion: function(){ + if (':' == this.peek().type) { + this.advance(); + return new nodes.Block(this.parseExpr()); + } else { + return this.block(); + } + }, + + /** + * case + */ + + parseCase: function(){ + var val = this.expect('case').val + , node = new nodes.Case(val); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * when + */ + + parseWhen: function(){ + var val = this.expect('when').val + return new nodes.Case.When(val, this.parseBlockExpansion()); + }, + + /** + * default + */ + + parseDefault: function(){ + this.expect('default'); + return new nodes.Case.When('default', this.parseBlockExpansion()); + }, + + /** + * code + */ + + parseCode: function(){ + var tok = this.expect('code') + , node = new nodes.Code(tok.val, tok.buffer, tok.escape) + , block + , i = 1; + node.line = this.line(); + while (this.lookahead(i) && 'newline' == this.lookahead(i).type) ++i; + block = 'indent' == this.lookahead(i).type; + if (block) { + this.skip(i-1); + node.block = this.block(); + } + return node; + }, + + /** + * comment + */ + + parseComment: function(){ + var tok = this.expect('comment') + , node; + + if ('indent' == this.peek().type) { + node = new nodes.BlockComment(tok.val, this.block(), tok.buffer); + } else { + node = new nodes.Comment(tok.val, tok.buffer); + } + + node.line = this.line(); + return node; + }, + + /** + * doctype + */ + + parseDoctype: function(){ + var tok = this.expect('doctype') + , node = new nodes.Doctype(tok.val); + node.line = this.line(); + return node; + }, + + /** + * filter attrs? text-block + */ + + parseFilter: function(){ + var block + , tok = this.expect('filter') + , attrs = this.accept('attrs'); + + this.lexer.pipeless = true; + block = this.parseTextBlock(); + this.lexer.pipeless = false; + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * tag ':' attrs? block + */ + + parseASTFilter: function(){ + var block + , tok = this.expect('tag') + , attrs = this.accept('attrs'); + + this.expect(':'); + block = this.block(); + + var node = new nodes.Filter(tok.val, block, attrs && attrs.attrs); + node.line = this.line(); + return node; + }, + + /** + * each block + */ + + parseEach: function(){ + var tok = this.expect('each') + , node = new nodes.Each(tok.code, tok.val, tok.key); + node.line = this.line(); + node.block = this.block(); + return node; + }, + + /** + * 'extends' name + */ + + parseExtends: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + if (!this.filename) + throw new Error('the "filename" option is required to extend templates'); + + var path = this.expect('extends').val.trim() + , dir = dirname(this.filename); + + var path = join(dir, path + '.jade') + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + + parser.blocks = this.blocks; + parser.contexts = this.contexts; + this.extending = parser; + + // TODO: null node + return new nodes.Literal(''); + }, + + /** + * 'block' name block + */ + + parseBlock: function(){ + var block = this.expect('block') + , mode = block.mode + , name = block.val.trim(); + + block = 'indent' == this.peek().type + ? this.block() + : new nodes.Block(new nodes.Literal('')); + + var prev = this.blocks[name]; + + if (prev) { + switch (prev.mode) { + case 'append': + block.nodes = block.nodes.concat(prev.nodes); + prev = block; + break; + case 'prepend': + block.nodes = prev.nodes.concat(block.nodes); + prev = block; + break; + } + } + + block.mode = mode; + return this.blocks[name] = prev || block; + }, + + /** + * include block? + */ + + parseInclude: function(){ + var path = require('path') + , fs = require('fs') + , dirname = path.dirname + , basename = path.basename + , join = path.join; + + var path = this.expect('include').val.trim() + , dir = dirname(this.filename); + + if (!this.filename) + throw new Error('the "filename" option is required to use includes'); + + // no extension + if (!~basename(path).indexOf('.')) { + path += '.jade'; + } + + // non-jade + if ('.jade' != path.substr(-5)) { + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8'); + return new nodes.Literal(str); + } + + var path = join(dir, path) + , str = fs.readFileSync(path, 'utf8') + , parser = new Parser(str, path, this.options); + parser.blocks = this.blocks; + parser.mixins = this.mixins; + + this.context(parser); + var ast = parser.parse(); + this.context(); + ast.filename = path; + + if ('indent' == this.peek().type) { + ast.includeBlock().push(this.block()); + } + + return ast; + }, + + /** + * call ident block + */ + + parseCall: function(){ + var tok = this.expect('call') + , name = tok.val + , args = tok.args + , mixin = new nodes.Mixin(name, args, new nodes.Block, true); + + this.tag(mixin); + if (mixin.block.isEmpty()) mixin.block = null; + return mixin; + }, + + /** + * mixin block + */ + + parseMixin: function(){ + var tok = this.expect('mixin') + , name = tok.val + , args = tok.args + , mixin; + + // definition + if ('indent' == this.peek().type) { + mixin = new nodes.Mixin(name, args, this.block(), false); + this.mixins[name] = mixin; + return mixin; + // call + } else { + return new nodes.Mixin(name, args, null, true); + } + }, + + /** + * indent (text | newline)* outdent + */ + + parseTextBlock: function(){ + var block = new nodes.Block; + block.line = this.line(); + var spaces = this.expect('indent').val; + if (null == this._spaces) this._spaces = spaces; + var indent = Array(spaces - this._spaces + 1).join(' '); + while ('outdent' != this.peek().type) { + switch (this.peek().type) { + case 'newline': + this.advance(); + break; + case 'indent': + this.parseTextBlock().nodes.forEach(function(node){ + block.push(node); + }); + break; + default: + var text = new nodes.Text(indent + this.advance().val); + text.line = this.line(); + block.push(text); + } + } + + if (spaces == this._spaces) this._spaces = null; + this.expect('outdent'); + return block; + }, + + /** + * indent expr* outdent + */ + + block: function(){ + var block = new nodes.Block; + block.line = this.line(); + this.expect('indent'); + while ('outdent' != this.peek().type) { + if ('newline' == this.peek().type) { + this.advance(); + } else { + block.push(this.parseExpr()); + } + } + this.expect('outdent'); + return block; + }, + + /** + * interpolation (attrs | class | id)* (text | code | ':')? newline* block? + */ + + parseInterpolation: function(){ + var tok = this.advance(); + var tag = new nodes.Tag(tok.val); + tag.buffer = true; + return this.tag(tag); + }, + + /** + * tag (attrs | class | id)* (text | code | ':')? newline* block? + */ + + parseTag: function(){ + // ast-filter look-ahead + var i = 2; + if ('attrs' == this.lookahead(i).type) ++i; + if (':' == this.lookahead(i).type) { + if ('indent' == this.lookahead(++i).type) { + return this.parseASTFilter(); + } + } + + var tok = this.advance() + , tag = new nodes.Tag(tok.val); + + tag.selfClosing = tok.selfClosing; + + return this.tag(tag); + }, + + /** + * Parse tag. + */ + + tag: function(tag){ + var dot; + + tag.line = this.line(); + + // (attrs | class | id)* + out: + while (true) { + switch (this.peek().type) { + case 'id': + case 'class': + var tok = this.advance(); + tag.setAttribute(tok.type, "'" + tok.val + "'"); + continue; + case 'attrs': + var tok = this.advance() + , obj = tok.attrs + , escaped = tok.escaped + , names = Object.keys(obj); + + if (tok.selfClosing) tag.selfClosing = true; + + for (var i = 0, len = names.length; i < len; ++i) { + var name = names[i] + , val = obj[name]; + tag.setAttribute(name, val, escaped[name]); + } + continue; + default: + break out; + } + } + + // check immediate '.' + if ('.' == this.peek().val) { + dot = tag.textOnly = true; + this.advance(); + } + + // (text | code | ':')? + switch (this.peek().type) { + case 'text': + tag.block.push(this.parseText()); + break; + case 'code': + tag.code = this.parseCode(); + break; + case ':': + this.advance(); + tag.block = new nodes.Block; + tag.block.push(this.parseExpr()); + break; + } + + // newline* + while ('newline' == this.peek().type) this.advance(); + + tag.textOnly = tag.textOnly || ~textOnly.indexOf(tag.name); + + // script special-case + if ('script' == tag.name) { + var type = tag.getAttribute('type'); + if (!dot && type && 'text/javascript' != type.replace(/^['"]|['"]$/g, '')) { + tag.textOnly = false; + } + } + + // block? + if ('indent' == this.peek().type) { + if (tag.textOnly) { + this.lexer.pipeless = true; + tag.block = this.parseTextBlock(); + this.lexer.pipeless = false; + } else { + var block = this.block(); + if (tag.block) { + for (var i = 0, len = block.nodes.length; i < len; ++i) { + tag.block.push(block.nodes[i]); + } + } else { + tag.block = block; + } + } + } + + return tag; + } +}; diff --git a/node_modules/mocha/node_modules/jade/lib/runtime.js b/node_modules/mocha/node_modules/jade/lib/runtime.js new file mode 100644 index 0000000..fb711f5 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/runtime.js @@ -0,0 +1,174 @@ + +/*! + * Jade - runtime + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Lame Array.isArray() polyfill for now. + */ + +if (!Array.isArray) { + Array.isArray = function(arr){ + return '[object Array]' == Object.prototype.toString.call(arr); + }; +} + +/** + * Lame Object.keys() polyfill for now. + */ + +if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } +} + +/** + * Merge two attribute objects giving precedence + * to values in object `b`. Classes are special-cased + * allowing for arrays and merging/joining appropriately + * resulting in a string. + * + * @param {Object} a + * @param {Object} b + * @return {Object} a + * @api private + */ + +exports.merge = function merge(a, b) { + var ac = a['class']; + var bc = b['class']; + + if (ac || bc) { + ac = ac || []; + bc = bc || []; + if (!Array.isArray(ac)) ac = [ac]; + if (!Array.isArray(bc)) bc = [bc]; + ac = ac.filter(nulls); + bc = bc.filter(nulls); + a['class'] = ac.concat(bc).join(' '); + } + + for (var key in b) { + if (key != 'class') { + a[key] = b[key]; + } + } + + return a; +}; + +/** + * Filter null `val`s. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function nulls(val) { + return val != null; +} + +/** + * Render the given attributes object. + * + * @param {Object} obj + * @param {Object} escaped + * @return {String} + * @api private + */ + +exports.attrs = function attrs(obj, escaped){ + var buf = [] + , terse = obj.terse; + + delete obj.terse; + var keys = Object.keys(obj) + , len = keys.length; + + if (len) { + buf.push(''); + for (var i = 0; i < len; ++i) { + var key = keys[i] + , val = obj[key]; + + if ('boolean' == typeof val || null == val) { + if (val) { + terse + ? buf.push(key) + : buf.push(key + '="' + key + '"'); + } + } else if (0 == key.indexOf('data') && 'string' != typeof val) { + buf.push(key + "='" + JSON.stringify(val) + "'"); + } else if ('class' == key && Array.isArray(val)) { + buf.push(key + '="' + exports.escape(val.join(' ')) + '"'); + } else if (escaped && escaped[key]) { + buf.push(key + '="' + exports.escape(val) + '"'); + } else { + buf.push(key + '="' + val + '"'); + } + } + } + + return buf.join(' '); +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function escape(html){ + return String(html) + .replace(/&(?!(\w+|\#\d+);)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Re-throw the given `err` in context to the + * the jade in `filename` at the given `lineno`. + * + * @param {Error} err + * @param {String} filename + * @param {String} lineno + * @api private + */ + +exports.rethrow = function rethrow(err, filename, lineno){ + if (!filename) throw err; + + var context = 3 + , str = require('fs').readFileSync(filename, 'utf8') + , lines = str.split('\n') + , start = Math.max(lineno - context, 0) + , end = Math.min(lines.length, lineno + context); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' > ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'Jade') + ':' + lineno + + '\n' + context + '\n\n' + err.message; + throw err; +}; diff --git a/node_modules/mocha/node_modules/jade/lib/self-closing.js b/node_modules/mocha/node_modules/jade/lib/self-closing.js new file mode 100644 index 0000000..0548771 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/self-closing.js @@ -0,0 +1,19 @@ + +/*! + * Jade - self closing tags + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +module.exports = [ + 'meta' + , 'img' + , 'link' + , 'input' + , 'source' + , 'area' + , 'base' + , 'col' + , 'br' + , 'hr' +]; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/lib/utils.js b/node_modules/mocha/node_modules/jade/lib/utils.js new file mode 100644 index 0000000..ff46d02 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/lib/utils.js @@ -0,0 +1,49 @@ + +/*! + * Jade - utils + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Convert interpolation in the given string to JavaScript. + * + * @param {String} str + * @return {String} + * @api private + */ + +var interpolate = exports.interpolate = function(str){ + return str.replace(/(\\)?([#!]){(.*?)}/g, function(str, escape, flag, code){ + return escape + ? str + : "' + " + + ('!' == flag ? '' : 'escape') + + "((interp = " + code.replace(/\\'/g, "'") + + ") == null ? '' : interp) + '"; + }); +}; + +/** + * Escape single quotes in `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +var escape = exports.escape = function(str) { + return str.replace(/'/g, "\\'"); +}; + +/** + * Interpolate, and escape the given `str`. + * + * @param {String} str + * @return {String} + * @api private + */ + +exports.text = function(str){ + return interpolate(escape(str)); +}; \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/.npmignore b/node_modules/mocha/node_modules/jade/node_modules/commander/.npmignore new file mode 100644 index 0000000..f1250e5 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/.npmignore @@ -0,0 +1,4 @@ +support +test +examples +*.sock diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/.travis.yml b/node_modules/mocha/node_modules/jade/node_modules/commander/.travis.yml new file mode 100644 index 0000000..f1d0f13 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.4 + - 0.6 diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/History.md b/node_modules/mocha/node_modules/jade/node_modules/commander/History.md new file mode 100644 index 0000000..4961d2e --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/History.md @@ -0,0 +1,107 @@ + +0.6.1 / 2012-06-01 +================== + + * Added: append (yes or no) on confirmation + * Added: allow node.js v0.7.x + +0.6.0 / 2012-04-10 +================== + + * Added `.prompt(obj, callback)` support. Closes #49 + * Added default support to .choose(). Closes #41 + * Fixed the choice example + +0.5.1 / 2011-12-20 +================== + + * Fixed `password()` for recent nodes. Closes #36 + +0.5.0 / 2011-12-04 +================== + + * Added sub-command option support [itay] + +0.4.3 / 2011-12-04 +================== + + * Fixed custom help ordering. Closes #32 + +0.4.2 / 2011-11-24 +================== + + * Added travis support + * Fixed: line-buffered input automatically trimmed. Closes #31 + +0.4.1 / 2011-11-18 +================== + + * Removed listening for "close" on --help + +0.4.0 / 2011-11-15 +================== + + * Added support for `--`. Closes #24 + +0.3.3 / 2011-11-14 +================== + + * Fixed: wait for close event when writing help info [Jerry Hamlet] + +0.3.2 / 2011-11-01 +================== + + * Fixed long flag definitions with values [felixge] + +0.3.1 / 2011-10-31 +================== + + * Changed `--version` short flag to `-V` from `-v` + * Changed `.version()` so it's configurable [felixge] + +0.3.0 / 2011-10-31 +================== + + * Added support for long flags only. Closes #18 + +0.2.1 / 2011-10-24 +================== + + * "node": ">= 0.4.x < 0.7.0". Closes #20 + +0.2.0 / 2011-09-26 +================== + + * Allow for defaults that are not just boolean. Default peassignment only occurs for --no-*, optional, and required arguments. [Jim Isaacs] + +0.1.0 / 2011-08-24 +================== + + * Added support for custom `--help` output + +0.0.5 / 2011-08-18 +================== + + * Changed: when the user enters nothing prompt for password again + * Fixed issue with passwords beginning with numbers [NuckChorris] + +0.0.4 / 2011-08-15 +================== + + * Fixed `Commander#args` + +0.0.3 / 2011-08-15 +================== + + * Added default option value support + +0.0.2 / 2011-08-15 +================== + + * Added mask support to `Command#password(str[, mask], fn)` + * Added `Command#password(str, fn)` + +0.0.1 / 2010-01-03 +================== + + * Initial release diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/Makefile b/node_modules/mocha/node_modules/jade/node_modules/commander/Makefile new file mode 100644 index 0000000..0074625 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/Makefile @@ -0,0 +1,7 @@ + +TESTS = $(shell find test/test.*.js) + +test: + @./test/run $(TESTS) + +.PHONY: test \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/Readme.md b/node_modules/mocha/node_modules/jade/node_modules/commander/Readme.md new file mode 100644 index 0000000..b8328c3 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/Readme.md @@ -0,0 +1,262 @@ +# Commander.js + + The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander). + + [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js) + +## Installation + + $ npm install commander + +## Option parsing + + Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('commander'); + +program + .version('0.0.1') + .option('-p, --peppers', 'Add peppers') + .option('-P, --pineapple', 'Add pineapple') + .option('-b, --bbq', 'Add bbq sauce') + .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') + .parse(process.argv); + +console.log('you ordered a pizza with:'); +if (program.peppers) console.log(' - peppers'); +if (program.pineapple) console.log(' - pineappe'); +if (program.bbq) console.log(' - bbq'); +console.log(' - %s cheese', program.cheese); +``` + + Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. + +## Automated --help + + The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: + +``` + $ ./examples/pizza --help + + Usage: pizza [options] + + Options: + + -V, --version output the version number + -p, --peppers Add peppers + -P, --pineapple Add pineappe + -b, --bbq Add bbq sauce + -c, --cheese Add the specified type of cheese [marble] + -h, --help output usage information + +``` + +## Coercion + +```js +function range(val) { + return val.split('..').map(Number); +} + +function list(val) { + return val.split(','); +} + +program + .version('0.0.1') + .usage('[options] ') + .option('-i, --integer ', 'An integer argument', parseInt) + .option('-f, --float ', 'A float argument', parseFloat) + .option('-r, --range ..', 'A range', range) + .option('-l, --list ', 'A list', list) + .option('-o, --optional [value]', 'An optional value') + .parse(process.argv); + +console.log(' int: %j', program.integer); +console.log(' float: %j', program.float); +console.log(' optional: %j', program.optional); +program.range = program.range || []; +console.log(' range: %j..%j', program.range[0], program.range[1]); +console.log(' list: %j', program.list); +console.log(' args: %j', program.args); +``` + +## Custom help + + You can display arbitrary `-h, --help` information + by listening for "--help". Commander will automatically + exit once you are done so that the remainder of your program + does not execute causing undesired behaviours, for example + in the following executable "stuff" will not output when + `--help` is used. + +```js +#!/usr/bin/env node + +/** + * Module dependencies. + */ + +var program = require('../'); + +function list(val) { + return val.split(',').map(Number); +} + +program + .version('0.0.1') + .option('-f, --foo', 'enable some foo') + .option('-b, --bar', 'enable some bar') + .option('-B, --baz', 'enable some baz'); + +// must be before .parse() since +// node's emit() is immediate + +program.on('--help', function(){ + console.log(' Examples:'); + console.log(''); + console.log(' $ custom-help --help'); + console.log(' $ custom-help -h'); + console.log(''); +}); + +program.parse(process.argv); + +console.log('stuff'); +``` + +yielding the following help output: + +``` + +Usage: custom-help [options] + +Options: + + -h, --help output usage information + -V, --version output the version number + -f, --foo enable some foo + -b, --bar enable some bar + -B, --baz enable some baz + +Examples: + + $ custom-help --help + $ custom-help -h + +``` + +## .prompt(msg, fn) + + Single-line prompt: + +```js +program.prompt('name: ', function(name){ + console.log('hi %s', name); +}); +``` + + Multi-line prompt: + +```js +program.prompt('description:', function(name){ + console.log('hi %s', name); +}); +``` + + Coercion: + +```js +program.prompt('Age: ', Number, function(age){ + console.log('age: %j', age); +}); +``` + +```js +program.prompt('Birthdate: ', Date, function(date){ + console.log('date: %s', date); +}); +``` + +## .password(msg[, mask], fn) + +Prompt for password without echoing: + +```js +program.password('Password: ', function(pass){ + console.log('got "%s"', pass); + process.stdin.destroy(); +}); +``` + +Prompt for password with mask char "*": + +```js +program.password('Password: ', '*', function(pass){ + console.log('got "%s"', pass); + process.stdin.destroy(); +}); +``` + +## .confirm(msg, fn) + + Confirm with the given `msg`: + +```js +program.confirm('continue? ', function(ok){ + console.log(' got %j', ok); +}); +``` + +## .choose(list, fn) + + Let the user choose from a `list`: + +```js +var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; + +console.log('Choose the coolest pet:'); +program.choose(list, function(i){ + console.log('you chose %d "%s"', i, list[i]); +}); +``` + +## Links + + - [API documentation](http://visionmedia.github.com/commander.js/) + - [ascii tables](https://github.com/LearnBoost/cli-table) + - [progress bars](https://github.com/visionmedia/node-progress) + - [more progress bars](https://github.com/substack/node-multimeter) + - [examples](https://github.com/visionmedia/commander.js/tree/master/examples) + +## License + +(The MIT License) + +Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> + +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. \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/index.js b/node_modules/mocha/node_modules/jade/node_modules/commander/index.js new file mode 100644 index 0000000..06ec1e4 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/commander'); \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/lib/commander.js b/node_modules/mocha/node_modules/jade/node_modules/commander/lib/commander.js new file mode 100644 index 0000000..5ba87eb --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/lib/commander.js @@ -0,0 +1,1026 @@ + +/*! + * commander + * Copyright(c) 2011 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var EventEmitter = require('events').EventEmitter + , path = require('path') + , tty = require('tty') + , basename = path.basename; + +/** + * Expose the root command. + */ + +exports = module.exports = new Command; + +/** + * Expose `Command`. + */ + +exports.Command = Command; + +/** + * Expose `Option`. + */ + +exports.Option = Option; + +/** + * Initialize a new `Option` with the given `flags` and `description`. + * + * @param {String} flags + * @param {String} description + * @api public + */ + +function Option(flags, description) { + this.flags = flags; + this.required = ~flags.indexOf('<'); + this.optional = ~flags.indexOf('['); + this.bool = !~flags.indexOf('-no-'); + flags = flags.split(/[ ,|]+/); + if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); + this.long = flags.shift(); + this.description = description; +} + +/** + * Return option name. + * + * @return {String} + * @api private + */ + +Option.prototype.name = function(){ + return this.long + .replace('--', '') + .replace('no-', ''); +}; + +/** + * Check if `arg` matches the short or long flag. + * + * @param {String} arg + * @return {Boolean} + * @api private + */ + +Option.prototype.is = function(arg){ + return arg == this.short + || arg == this.long; +}; + +/** + * Initialize a new `Command`. + * + * @param {String} name + * @api public + */ + +function Command(name) { + this.commands = []; + this.options = []; + this.args = []; + this.name = name; +} + +/** + * Inherit from `EventEmitter.prototype`. + */ + +Command.prototype.__proto__ = EventEmitter.prototype; + +/** + * Add command `name`. + * + * The `.action()` callback is invoked when the + * command `name` is specified via __ARGV__, + * and the remaining arguments are applied to the + * function for access. + * + * When the `name` is "*" an un-matched command + * will be passed as the first arg, followed by + * the rest of __ARGV__ remaining. + * + * Examples: + * + * program + * .version('0.0.1') + * .option('-C, --chdir ', 'change the working directory') + * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') + * .option('-T, --no-tests', 'ignore test hook') + * + * program + * .command('setup') + * .description('run remote setup commands') + * .action(function(){ + * console.log('setup'); + * }); + * + * program + * .command('exec ') + * .description('run the given remote command') + * .action(function(cmd){ + * console.log('exec "%s"', cmd); + * }); + * + * program + * .command('*') + * .description('deploy the given env') + * .action(function(env){ + * console.log('deploying "%s"', env); + * }); + * + * program.parse(process.argv); + * + * @param {String} name + * @return {Command} the new command + * @api public + */ + +Command.prototype.command = function(name){ + var args = name.split(/ +/); + var cmd = new Command(args.shift()); + this.commands.push(cmd); + cmd.parseExpectedArgs(args); + cmd.parent = this; + return cmd; +}; + +/** + * Parse expected `args`. + * + * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. + * + * @param {Array} args + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parseExpectedArgs = function(args){ + if (!args.length) return; + var self = this; + args.forEach(function(arg){ + switch (arg[0]) { + case '<': + self.args.push({ required: true, name: arg.slice(1, -1) }); + break; + case '[': + self.args.push({ required: false, name: arg.slice(1, -1) }); + break; + } + }); + return this; +}; + +/** + * Register callback `fn` for the command. + * + * Examples: + * + * program + * .command('help') + * .description('display verbose help') + * .action(function(){ + * // output help here + * }); + * + * @param {Function} fn + * @return {Command} for chaining + * @api public + */ + +Command.prototype.action = function(fn){ + var self = this; + this.parent.on(this.name, function(args, unknown){ + // Parse any so-far unknown options + unknown = unknown || []; + var parsed = self.parseOptions(unknown); + + // Output help if necessary + outputHelpIfNecessary(self, parsed.unknown); + + // If there are still any unknown options, then we simply + // die, unless someone asked for help, in which case we give it + // to them, and then we die. + if (parsed.unknown.length > 0) { + self.unknownOption(parsed.unknown[0]); + } + + self.args.forEach(function(arg, i){ + if (arg.required && null == args[i]) { + self.missingArgument(arg.name); + } + }); + + // Always append ourselves to the end of the arguments, + // to make sure we match the number of arguments the user + // expects + if (self.args.length) { + args[self.args.length] = self; + } else { + args.push(self); + } + + fn.apply(this, args); + }); + return this; +}; + +/** + * Define option with `flags`, `description` and optional + * coercion `fn`. + * + * The `flags` string should contain both the short and long flags, + * separated by comma, a pipe or space. The following are all valid + * all will output this way when `--help` is used. + * + * "-p, --pepper" + * "-p|--pepper" + * "-p --pepper" + * + * Examples: + * + * // simple boolean defaulting to false + * program.option('-p, --pepper', 'add pepper'); + * + * --pepper + * program.pepper + * // => Boolean + * + * // simple boolean defaulting to false + * program.option('-C, --no-cheese', 'remove cheese'); + * + * program.cheese + * // => true + * + * --no-cheese + * program.cheese + * // => true + * + * // required argument + * program.option('-C, --chdir ', 'change the working directory'); + * + * --chdir /tmp + * program.chdir + * // => "/tmp" + * + * // optional argument + * program.option('-c, --cheese [type]', 'add cheese [marble]'); + * + * @param {String} flags + * @param {String} description + * @param {Function|Mixed} fn or default + * @param {Mixed} defaultValue + * @return {Command} for chaining + * @api public + */ + +Command.prototype.option = function(flags, description, fn, defaultValue){ + var self = this + , option = new Option(flags, description) + , oname = option.name() + , name = camelcase(oname); + + // default as 3rd arg + if ('function' != typeof fn) defaultValue = fn, fn = null; + + // preassign default value only for --no-*, [optional], or + if (false == option.bool || option.optional || option.required) { + // when --no-* we make sure default is true + if (false == option.bool) defaultValue = true; + // preassign only if we have a default + if (undefined !== defaultValue) self[name] = defaultValue; + } + + // register the option + this.options.push(option); + + // when it's passed assign the value + // and conditionally invoke the callback + this.on(oname, function(val){ + // coercion + if (null != val && fn) val = fn(val); + + // unassigned or bool + if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) { + // if no value, bool true, and we have a default, then use it! + if (null == val) { + self[name] = option.bool + ? defaultValue || true + : false; + } else { + self[name] = val; + } + } else if (null !== val) { + // reassign + self[name] = val; + } + }); + + return this; +}; + +/** + * Parse `argv`, settings options and invoking commands when defined. + * + * @param {Array} argv + * @return {Command} for chaining + * @api public + */ + +Command.prototype.parse = function(argv){ + // store raw args + this.rawArgs = argv; + + // guess name + if (!this.name) this.name = basename(argv[1]); + + // process argv + var parsed = this.parseOptions(this.normalize(argv.slice(2))); + this.args = parsed.args; + return this.parseArgs(this.args, parsed.unknown); +}; + +/** + * Normalize `args`, splitting joined short flags. For example + * the arg "-abc" is equivalent to "-a -b -c". + * + * @param {Array} args + * @return {Array} + * @api private + */ + +Command.prototype.normalize = function(args){ + var ret = [] + , arg; + + for (var i = 0, len = args.length; i < len; ++i) { + arg = args[i]; + if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) { + arg.slice(1).split('').forEach(function(c){ + ret.push('-' + c); + }); + } else { + ret.push(arg); + } + } + + return ret; +}; + +/** + * Parse command `args`. + * + * When listener(s) are available those + * callbacks are invoked, otherwise the "*" + * event is emitted and those actions are invoked. + * + * @param {Array} args + * @return {Command} for chaining + * @api private + */ + +Command.prototype.parseArgs = function(args, unknown){ + var cmds = this.commands + , len = cmds.length + , name; + + if (args.length) { + name = args[0]; + if (this.listeners(name).length) { + this.emit(args.shift(), args, unknown); + } else { + this.emit('*', args); + } + } else { + outputHelpIfNecessary(this, unknown); + + // If there were no args and we have unknown options, + // then they are extraneous and we need to error. + if (unknown.length > 0) { + this.unknownOption(unknown[0]); + } + } + + return this; +}; + +/** + * Return an option matching `arg` if any. + * + * @param {String} arg + * @return {Option} + * @api private + */ + +Command.prototype.optionFor = function(arg){ + for (var i = 0, len = this.options.length; i < len; ++i) { + if (this.options[i].is(arg)) { + return this.options[i]; + } + } +}; + +/** + * Parse options from `argv` returning `argv` + * void of these options. + * + * @param {Array} argv + * @return {Array} + * @api public + */ + +Command.prototype.parseOptions = function(argv){ + var args = [] + , len = argv.length + , literal + , option + , arg; + + var unknownOptions = []; + + // parse options + for (var i = 0; i < len; ++i) { + arg = argv[i]; + + // literal args after -- + if ('--' == arg) { + literal = true; + continue; + } + + if (literal) { + args.push(arg); + continue; + } + + // find matching Option + option = this.optionFor(arg); + + // option is defined + if (option) { + // requires arg + if (option.required) { + arg = argv[++i]; + if (null == arg) return this.optionMissingArgument(option); + if ('-' == arg[0]) return this.optionMissingArgument(option, arg); + this.emit(option.name(), arg); + // optional arg + } else if (option.optional) { + arg = argv[i+1]; + if (null == arg || '-' == arg[0]) { + arg = null; + } else { + ++i; + } + this.emit(option.name(), arg); + // bool + } else { + this.emit(option.name()); + } + continue; + } + + // looks like an option + if (arg.length > 1 && '-' == arg[0]) { + unknownOptions.push(arg); + + // If the next argument looks like it might be + // an argument for this option, we pass it on. + // If it isn't, then it'll simply be ignored + if (argv[i+1] && '-' != argv[i+1][0]) { + unknownOptions.push(argv[++i]); + } + continue; + } + + // arg + args.push(arg); + } + + return { args: args, unknown: unknownOptions }; +}; + +/** + * Argument `name` is missing. + * + * @param {String} name + * @api private + */ + +Command.prototype.missingArgument = function(name){ + console.error(); + console.error(" error: missing required argument `%s'", name); + console.error(); + process.exit(1); +}; + +/** + * `Option` is missing an argument, but received `flag` or nothing. + * + * @param {String} option + * @param {String} flag + * @api private + */ + +Command.prototype.optionMissingArgument = function(option, flag){ + console.error(); + if (flag) { + console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); + } else { + console.error(" error: option `%s' argument missing", option.flags); + } + console.error(); + process.exit(1); +}; + +/** + * Unknown option `flag`. + * + * @param {String} flag + * @api private + */ + +Command.prototype.unknownOption = function(flag){ + console.error(); + console.error(" error: unknown option `%s'", flag); + console.error(); + process.exit(1); +}; + +/** + * Set the program version to `str`. + * + * This method auto-registers the "-V, --version" flag + * which will print the version number when passed. + * + * @param {String} str + * @param {String} flags + * @return {Command} for chaining + * @api public + */ + +Command.prototype.version = function(str, flags){ + if (0 == arguments.length) return this._version; + this._version = str; + flags = flags || '-V, --version'; + this.option(flags, 'output the version number'); + this.on('version', function(){ + console.log(str); + process.exit(0); + }); + return this; +}; + +/** + * Set the description `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.description = function(str){ + if (0 == arguments.length) return this._description; + this._description = str; + return this; +}; + +/** + * Set / get the command usage `str`. + * + * @param {String} str + * @return {String|Command} + * @api public + */ + +Command.prototype.usage = function(str){ + var args = this.args.map(function(arg){ + return arg.required + ? '<' + arg.name + '>' + : '[' + arg.name + ']'; + }); + + var usage = '[options' + + (this.commands.length ? '] [command' : '') + + ']' + + (this.args.length ? ' ' + args : ''); + if (0 == arguments.length) return this._usage || usage; + this._usage = str; + + return this; +}; + +/** + * Return the largest option length. + * + * @return {Number} + * @api private + */ + +Command.prototype.largestOptionLength = function(){ + return this.options.reduce(function(max, option){ + return Math.max(max, option.flags.length); + }, 0); +}; + +/** + * Return help for options. + * + * @return {String} + * @api private + */ + +Command.prototype.optionHelp = function(){ + var width = this.largestOptionLength(); + + // Prepend the help information + return [pad('-h, --help', width) + ' ' + 'output usage information'] + .concat(this.options.map(function(option){ + return pad(option.flags, width) + + ' ' + option.description; + })) + .join('\n'); +}; + +/** + * Return command help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.commandHelp = function(){ + if (!this.commands.length) return ''; + return [ + '' + , ' Commands:' + , '' + , this.commands.map(function(cmd){ + var args = cmd.args.map(function(arg){ + return arg.required + ? '<' + arg.name + '>' + : '[' + arg.name + ']'; + }).join(' '); + + return cmd.name + + (cmd.options.length + ? ' [options]' + : '') + ' ' + args + + (cmd.description() + ? '\n' + cmd.description() + : ''); + }).join('\n\n').replace(/^/gm, ' ') + , '' + ].join('\n'); +}; + +/** + * Return program help documentation. + * + * @return {String} + * @api private + */ + +Command.prototype.helpInformation = function(){ + return [ + '' + , ' Usage: ' + this.name + ' ' + this.usage() + , '' + this.commandHelp() + , ' Options:' + , '' + , '' + this.optionHelp().replace(/^/gm, ' ') + , '' + , '' + ].join('\n'); +}; + +/** + * Prompt for a `Number`. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptForNumber = function(str, fn){ + var self = this; + this.promptSingleLine(str, function parseNumber(val){ + val = Number(val); + if (isNaN(val)) return self.promptSingleLine(str + '(must be a number) ', parseNumber); + fn(val); + }); +}; + +/** + * Prompt for a `Date`. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptForDate = function(str, fn){ + var self = this; + this.promptSingleLine(str, function parseDate(val){ + val = new Date(val); + if (isNaN(val.getTime())) return self.promptSingleLine(str + '(must be a date) ', parseDate); + fn(val); + }); +}; + +/** + * Single-line prompt. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptSingleLine = function(str, fn){ + if ('function' == typeof arguments[2]) { + return this['promptFor' + (fn.name || fn)](str, arguments[2]); + } + + process.stdout.write(str); + process.stdin.setEncoding('utf8'); + process.stdin.once('data', function(val){ + fn(val.trim()); + }).resume(); +}; + +/** + * Multi-line prompt. + * + * @param {String} str + * @param {Function} fn + * @api private + */ + +Command.prototype.promptMultiLine = function(str, fn){ + var buf = []; + console.log(str); + process.stdin.setEncoding('utf8'); + process.stdin.on('data', function(val){ + if ('\n' == val || '\r\n' == val) { + process.stdin.removeAllListeners('data'); + fn(buf.join('\n')); + } else { + buf.push(val.trimRight()); + } + }).resume(); +}; + +/** + * Prompt `str` and callback `fn(val)` + * + * Commander supports single-line and multi-line prompts. + * To issue a single-line prompt simply add white-space + * to the end of `str`, something like "name: ", whereas + * for a multi-line prompt omit this "description:". + * + * + * Examples: + * + * program.prompt('Username: ', function(name){ + * console.log('hi %s', name); + * }); + * + * program.prompt('Description:', function(desc){ + * console.log('description was "%s"', desc.trim()); + * }); + * + * @param {String|Object} str + * @param {Function} fn + * @api public + */ + +Command.prototype.prompt = function(str, fn){ + var self = this; + + if ('string' == typeof str) { + if (/ $/.test(str)) return this.promptSingleLine.apply(this, arguments); + this.promptMultiLine(str, fn); + } else { + var keys = Object.keys(str) + , obj = {}; + + function next() { + var key = keys.shift() + , label = str[key]; + + if (!key) return fn(obj); + self.prompt(label, function(val){ + obj[key] = val; + next(); + }); + } + + next(); + } +}; + +/** + * Prompt for password with `str`, `mask` char and callback `fn(val)`. + * + * The mask string defaults to '', aka no output is + * written while typing, you may want to use "*" etc. + * + * Examples: + * + * program.password('Password: ', function(pass){ + * console.log('got "%s"', pass); + * process.stdin.destroy(); + * }); + * + * program.password('Password: ', '*', function(pass){ + * console.log('got "%s"', pass); + * process.stdin.destroy(); + * }); + * + * @param {String} str + * @param {String} mask + * @param {Function} fn + * @api public + */ + +Command.prototype.password = function(str, mask, fn){ + var self = this + , buf = ''; + + // default mask + if ('function' == typeof mask) { + fn = mask; + mask = ''; + } + + process.stdin.resume(); + tty.setRawMode(true); + process.stdout.write(str); + + // keypress + process.stdin.on('keypress', function(c, key){ + if (key && 'enter' == key.name) { + console.log(); + process.stdin.removeAllListeners('keypress'); + tty.setRawMode(false); + if (!buf.trim().length) return self.password(str, mask, fn); + fn(buf); + return; + } + + if (key && key.ctrl && 'c' == key.name) { + console.log('%s', buf); + process.exit(); + } + + process.stdout.write(mask); + buf += c; + }).resume(); +}; + +/** + * Confirmation prompt with `str` and callback `fn(bool)` + * + * Examples: + * + * program.confirm('continue? ', function(ok){ + * console.log(' got %j', ok); + * process.stdin.destroy(); + * }); + * + * @param {String} str + * @param {Function} fn + * @api public + */ + + +Command.prototype.confirm = function(str, fn, verbose){ + var self = this; + this.prompt(str, function(ok){ + if (!ok.trim()) { + if (!verbose) str += '(yes or no) '; + return self.confirm(str, fn, true); + } + fn(parseBool(ok)); + }); +}; + +/** + * Choice prompt with `list` of items and callback `fn(index, item)` + * + * Examples: + * + * var list = ['tobi', 'loki', 'jane', 'manny', 'luna']; + * + * console.log('Choose the coolest pet:'); + * program.choose(list, function(i){ + * console.log('you chose %d "%s"', i, list[i]); + * process.stdin.destroy(); + * }); + * + * @param {Array} list + * @param {Number|Function} index or fn + * @param {Function} fn + * @api public + */ + +Command.prototype.choose = function(list, index, fn){ + var self = this + , hasDefault = 'number' == typeof index; + + if (!hasDefault) { + fn = index; + index = null; + } + + list.forEach(function(item, i){ + if (hasDefault && i == index) { + console.log('* %d) %s', i + 1, item); + } else { + console.log(' %d) %s', i + 1, item); + } + }); + + function again() { + self.prompt(' : ', function(val){ + val = parseInt(val, 10) - 1; + if (hasDefault && isNaN(val)) val = index; + + if (null == list[val]) { + again(); + } else { + fn(val, list[val]); + } + }); + } + + again(); +}; + +/** + * Camel-case the given `flag` + * + * @param {String} flag + * @return {String} + * @api private + */ + +function camelcase(flag) { + return flag.split('-').reduce(function(str, word){ + return str + word[0].toUpperCase() + word.slice(1); + }); +} + +/** + * Parse a boolean `str`. + * + * @param {String} str + * @return {Boolean} + * @api private + */ + +function parseBool(str) { + return /^y|yes|ok|true$/i.test(str); +} + +/** + * Pad `str` to `width`. + * + * @param {String} str + * @param {Number} width + * @return {String} + * @api private + */ + +function pad(str, width) { + var len = Math.max(0, width - str.length); + return str + Array(len + 1).join(' '); +} + +/** + * Output help information if necessary + * + * @param {Command} command to output help for + * @param {Array} array of options to search for -h or --help + * @api private + */ + +function outputHelpIfNecessary(cmd, options) { + options = options || []; + for (var i = 0; i < options.length; i++) { + if (options[i] == '--help' || options[i] == '-h') { + process.stdout.write(cmd.helpInformation()); + cmd.emit('--help'); + process.exit(0); + } + } +} diff --git a/node_modules/mocha/node_modules/jade/node_modules/commander/package.json b/node_modules/mocha/node_modules/jade/node_modules/commander/package.json new file mode 100644 index 0000000..4dda069 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/commander/package.json @@ -0,0 +1,60 @@ +{ + "name": "commander", + "version": "0.6.1", + "description": "the complete solution for node.js command-line programs", + "keywords": [ + "command", + "option", + "parser", + "prompt", + "stdin" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/commander.js.git" + }, + "dependencies": {}, + "devDependencies": { + "should": ">= 0.0.1" + }, + "scripts": { + "test": "make test" + }, + "main": "index", + "engines": { + "node": ">= 0.4.x" + }, + "_npmUser": { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + }, + "_id": "commander@0.6.1", + "optionalDependencies": {}, + "_engineSupported": true, + "_npmVersion": "1.1.0-3", + "_nodeVersion": "v0.6.12", + "_defaultsLoaded": true, + "dist": { + "shasum": "fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06", + "tarball": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" + }, + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "directories": {}, + "_shasum": "fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06", + "_resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "_from": "commander@0.6.1", + "bugs": { + "url": "https://github.com/visionmedia/commander.js/issues" + }, + "readme": "ERROR: No README data found!", + "homepage": "https://github.com/visionmedia/commander.js#readme" +} diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.orig @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej new file mode 100644 index 0000000..69244ff --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.gitignore.rej @@ -0,0 +1,5 @@ +--- /dev/null ++++ .gitignore +@@ -0,0 +1,2 @@ ++node_modules/ ++npm-debug.log \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore new file mode 100644 index 0000000..9303c34 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/.npmignore @@ -0,0 +1,2 @@ +node_modules/ +npm-debug.log \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000..432d1ae --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: + +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. diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown new file mode 100644 index 0000000..b4dd75f --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/README.markdown @@ -0,0 +1,54 @@ +mkdirp +====== + +Like `mkdir -p`, but in node.js! + +example +======= + +pow.js +------ + var mkdirp = require('mkdirp'); + + mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') + }); + +Output + pow! + +And now /tmp/foo/bar/baz exists, huzzah! + +methods +======= + +var mkdirp = require('mkdirp'); + +mkdirp(dir, mode, cb) +--------------------- + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `mode`. + +If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +mkdirp.sync(dir, mode) +---------------------- + +Synchronously create a new directory and any necessary subdirectories at `dir` +with octal permission string `mode`. + +If `mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +install +======= + +With [npm](http://npmjs.org) do: + + npm install mkdirp + +license +======= + +MIT/X11 diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000..e692421 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig new file mode 100644 index 0000000..7741462 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.orig @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej new file mode 100644 index 0000000..81e7f43 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/examples/pow.js.rej @@ -0,0 +1,19 @@ +--- examples/pow.js ++++ examples/pow.js +@@ -1,6 +1,15 @@ +-var mkdirp = require('mkdirp').mkdirp; ++var mkdirp = require('../').mkdirp, ++ mkdirpSync = require('../').mkdirpSync; + + mkdirp('/tmp/foo/bar/baz', 0755, function (err) { + if (err) console.error(err) + else console.log('pow!') + }); ++ ++try { ++ mkdirpSync('/tmp/bar/foo/baz', 0755); ++ console.log('double pow!'); ++} ++catch (ex) { ++ console.log(ex); ++} \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js new file mode 100644 index 0000000..25f43ad --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/index.js @@ -0,0 +1,79 @@ +var path = require('path'); +var fs = require('fs'); + +module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP; + +function mkdirP (p, mode, f) { + if (typeof mode === 'function' || mode === undefined) { + f = mode; + mode = 0777 & (~process.umask()); + } + + var cb = f || function () {}; + if (typeof mode === 'string') mode = parseInt(mode, 8); + p = path.resolve(p); + + fs.mkdir(p, mode, function (er) { + if (!er) return cb(); + switch (er.code) { + case 'ENOENT': + mkdirP(path.dirname(p), mode, function (er) { + if (er) cb(er); + else mkdirP(p, mode, cb); + }); + break; + + case 'EEXIST': + fs.stat(p, function (er2, stat) { + // if the stat fails, then that's super weird. + // let the original EEXIST be the failure reason. + if (er2 || !stat.isDirectory()) cb(er) + else cb(); + }); + break; + + default: + cb(er); + break; + } + }); +} + +mkdirP.sync = function sync (p, mode) { + if (mode === undefined) { + mode = 0777 & (~process.umask()); + } + + if (typeof mode === 'string') mode = parseInt(mode, 8); + p = path.resolve(p); + + try { + fs.mkdirSync(p, mode) + } + catch (err0) { + switch (err0.code) { + case 'ENOENT' : + var err1 = sync(path.dirname(p), mode) + if (err1) throw err1; + else return sync(p, mode); + break; + + case 'EEXIST' : + var stat; + try { + stat = fs.statSync(p); + } + catch (err1) { + throw err0 + } + if (!stat.isDirectory()) throw err0; + else return null; + break; + default : + throw err0 + break; + } + } + + return null; +}; diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json new file mode 100644 index 0000000..8fe36d6 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/package.json @@ -0,0 +1,58 @@ +{ + "name": "mkdirp", + "description": "Recursively mkdir, like `mkdir -p`", + "version": "0.3.0", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "main": "./index", + "keywords": [ + "mkdir", + "directory" + ], + "repository": { + "type": "git", + "url": "git://github.com/substack/node-mkdirp.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "devDependencies": { + "tap": "0.0.x" + }, + "license": "MIT/X11", + "engines": { + "node": "*" + }, + "_npmUser": { + "name": "substack", + "email": "mail@substack.net" + }, + "_id": "mkdirp@0.3.0", + "dependencies": {}, + "_engineSupported": true, + "_npmVersion": "1.0.106", + "_nodeVersion": "v0.4.12", + "_defaultsLoaded": true, + "dist": { + "shasum": "1bbf5ab1ba827af23575143490426455f481fe1e", + "tarball": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz" + }, + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "directories": {}, + "_shasum": "1bbf5ab1ba827af23575143490426455f481fe1e", + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "_from": "mkdirp@0.3.0", + "bugs": { + "url": "https://github.com/substack/node-mkdirp/issues" + }, + "readme": "ERROR: No README data found!", + "homepage": "https://github.com/substack/node-mkdirp#readme" +} diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js new file mode 100644 index 0000000..520dcb8 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/chmod.js @@ -0,0 +1,38 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = 0744 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & 0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = 0755 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js new file mode 100644 index 0000000..0eb7099 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/clobber.js @@ -0,0 +1,37 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkdirp(file, 0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000..b07cd70 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('woo', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js new file mode 100644 index 0000000..23a7abb --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('async perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); + +test('async root perm', function (t) { + mkdirp('/tmp', 0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js new file mode 100644 index 0000000..f685f60 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/perm_sync.js @@ -0,0 +1,39 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync perm', function (t) { + t.plan(2); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); + +test('sync root perm', function (t) { + t.plan(1); + + var file = '/tmp'; + mkdirp.sync(file, 0755); + path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000..96a0447 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/race.js @@ -0,0 +1,41 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('race', function (t) { + t.plan(4); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file, function () { + if (--res === 0) t.end(); + }); + + mk(file, function () { + if (--res === 0) t.end(); + }); + + function mk (file, cb) { + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + if (cb) cb(); + } + }) + }) + }); + } +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000..7985824 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/rel.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('rel', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, 0755, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + process.chdir(cwd); + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js new file mode 100644 index 0000000..e0e389d --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/sync.js @@ -0,0 +1,27 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('sync', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + var err = mkdirp.sync(file, 0755); + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0755); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js new file mode 100644 index 0000000..64ccafe --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('implicit mode from umask', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, function (err) { + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, 0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) + }); +}); diff --git a/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js new file mode 100644 index 0000000..83cba56 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/node_modules/mkdirp/test/umask_sync.js @@ -0,0 +1,27 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('umask sync modes', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + var err = mkdirp.sync(file); + if (err) t.fail(err); + else path.exists(file, function (ex) { + if (!ex) t.fail('file not created') + else fs.stat(file, function (err, stat) { + if (err) t.fail(err) + else { + t.equal(stat.mode & 0777, (0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + t.end(); + } + }) + }) +}); diff --git a/node_modules/mocha/node_modules/jade/package.json b/node_modules/mocha/node_modules/jade/package.json new file mode 100644 index 0000000..0b279ee --- /dev/null +++ b/node_modules/mocha/node_modules/jade/package.json @@ -0,0 +1,62 @@ +{ + "name": "jade", + "description": "Jade template engine", + "version": "0.26.3", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "repository": { + "type": "git", + "url": "git://github.com/visionmedia/jade.git" + }, + "main": "./index.js", + "bin": { + "jade": "./bin/jade" + }, + "man": [ + "./jade.1" + ], + "dependencies": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "devDependencies": { + "mocha": "*", + "markdown": "*", + "stylus": "*", + "uubench": "*", + "should": "*", + "less": "*", + "uglify-js": "*" + }, + "component": { + "scripts": { + "jade": "runtime.js" + } + }, + "scripts": { + "prepublish": "npm prune" + }, + "_id": "jade@0.26.3", + "dist": { + "shasum": "8f10d7977d8d79f2f6ff862a81b0513ccb25686c", + "tarball": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz" + }, + "maintainers": [ + { + "name": "tjholowaychuk", + "email": "tj@vision-media.ca" + } + ], + "directories": {}, + "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", + "_shasum": "8f10d7977d8d79f2f6ff862a81b0513ccb25686c", + "_resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "_from": "jade@0.26.3", + "bugs": { + "url": "https://github.com/visionmedia/jade/issues" + }, + "readme": "ERROR: No README data found!", + "homepage": "https://github.com/visionmedia/jade#readme" +} diff --git a/node_modules/mocha/node_modules/jade/runtime.js b/node_modules/mocha/node_modules/jade/runtime.js new file mode 100644 index 0000000..0f54907 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/runtime.js @@ -0,0 +1,179 @@ + +jade = (function(exports){ +/*! + * Jade - runtime + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Lame Array.isArray() polyfill for now. + */ + +if (!Array.isArray) { + Array.isArray = function(arr){ + return '[object Array]' == Object.prototype.toString.call(arr); + }; +} + +/** + * Lame Object.keys() polyfill for now. + */ + +if (!Object.keys) { + Object.keys = function(obj){ + var arr = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + arr.push(key); + } + } + return arr; + } +} + +/** + * Merge two attribute objects giving precedence + * to values in object `b`. Classes are special-cased + * allowing for arrays and merging/joining appropriately + * resulting in a string. + * + * @param {Object} a + * @param {Object} b + * @return {Object} a + * @api private + */ + +exports.merge = function merge(a, b) { + var ac = a['class']; + var bc = b['class']; + + if (ac || bc) { + ac = ac || []; + bc = bc || []; + if (!Array.isArray(ac)) ac = [ac]; + if (!Array.isArray(bc)) bc = [bc]; + ac = ac.filter(nulls); + bc = bc.filter(nulls); + a['class'] = ac.concat(bc).join(' '); + } + + for (var key in b) { + if (key != 'class') { + a[key] = b[key]; + } + } + + return a; +}; + +/** + * Filter null `val`s. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + +function nulls(val) { + return val != null; +} + +/** + * Render the given attributes object. + * + * @param {Object} obj + * @param {Object} escaped + * @return {String} + * @api private + */ + +exports.attrs = function attrs(obj, escaped){ + var buf = [] + , terse = obj.terse; + + delete obj.terse; + var keys = Object.keys(obj) + , len = keys.length; + + if (len) { + buf.push(''); + for (var i = 0; i < len; ++i) { + var key = keys[i] + , val = obj[key]; + + if ('boolean' == typeof val || null == val) { + if (val) { + terse + ? buf.push(key) + : buf.push(key + '="' + key + '"'); + } + } else if (0 == key.indexOf('data') && 'string' != typeof val) { + buf.push(key + "='" + JSON.stringify(val) + "'"); + } else if ('class' == key && Array.isArray(val)) { + buf.push(key + '="' + exports.escape(val.join(' ')) + '"'); + } else if (escaped && escaped[key]) { + buf.push(key + '="' + exports.escape(val) + '"'); + } else { + buf.push(key + '="' + val + '"'); + } + } + } + + return buf.join(' '); +}; + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function escape(html){ + return String(html) + .replace(/&(?!(\w+|\#\d+);)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +/** + * Re-throw the given `err` in context to the + * the jade in `filename` at the given `lineno`. + * + * @param {Error} err + * @param {String} filename + * @param {String} lineno + * @api private + */ + +exports.rethrow = function rethrow(err, filename, lineno){ + if (!filename) throw err; + + var context = 3 + , str = require('fs').readFileSync(filename, 'utf8') + , lines = str.split('\n') + , start = Math.max(lineno - context, 0) + , end = Math.min(lines.length, lineno + context); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' > ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'Jade') + ':' + lineno + + '\n' + context + '\n\n' + err.message; + throw err; +}; + + return exports; + +})({}); diff --git a/node_modules/mocha/node_modules/jade/runtime.min.js b/node_modules/mocha/node_modules/jade/runtime.min.js new file mode 100644 index 0000000..1714efb --- /dev/null +++ b/node_modules/mocha/node_modules/jade/runtime.min.js @@ -0,0 +1 @@ +jade=function(exports){Array.isArray||(Array.isArray=function(arr){return"[object Array]"==Object.prototype.toString.call(arr)}),Object.keys||(Object.keys=function(obj){var arr=[];for(var key in obj)obj.hasOwnProperty(key)&&arr.push(key);return arr}),exports.merge=function merge(a,b){var ac=a["class"],bc=b["class"];if(ac||bc)ac=ac||[],bc=bc||[],Array.isArray(ac)||(ac=[ac]),Array.isArray(bc)||(bc=[bc]),ac=ac.filter(nulls),bc=bc.filter(nulls),a["class"]=ac.concat(bc).join(" ");for(var key in b)key!="class"&&(a[key]=b[key]);return a};function nulls(val){return val!=null}return exports.attrs=function attrs(obj,escaped){var buf=[],terse=obj.terse;delete obj.terse;var keys=Object.keys(obj),len=keys.length;if(len){buf.push("");for(var i=0;i/g,">").replace(/"/g,""")},exports.rethrow=function rethrow(err,filename,lineno){if(!filename)throw err;var context=3,str=require("fs").readFileSync(filename,"utf8"),lines=str.split("\n"),start=Math.max(lineno-context,0),end=Math.min(lines.length,lineno+context),context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" > ":" ")+curr+"| "+line}).join("\n");throw err.path=filename,err.message=(filename||"Jade")+":"+lineno+"\n"+context+"\n\n"+err.message,err},exports}({}); \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/test.jade b/node_modules/mocha/node_modules/jade/test.jade new file mode 100644 index 0000000..b3a8988 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/test.jade @@ -0,0 +1,7 @@ +p. + This is a large + body of text for + this tag. + + Nothing too + exciting. \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/testing/head.jade b/node_modules/mocha/node_modules/jade/testing/head.jade new file mode 100644 index 0000000..8515406 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/testing/head.jade @@ -0,0 +1,5 @@ +head + script(src='/jquery.js') + yield + if false + script(src='/jquery.ui.js') diff --git a/node_modules/mocha/node_modules/jade/testing/index.jade b/node_modules/mocha/node_modules/jade/testing/index.jade new file mode 100644 index 0000000..1032c5f --- /dev/null +++ b/node_modules/mocha/node_modules/jade/testing/index.jade @@ -0,0 +1,22 @@ + +tag = 'p' +foo = 'bar' + +#{tag} value +#{tag}(foo='bar') value +#{foo ? 'a' : 'li'}(something) here + +mixin item(icon) + li + if attributes.href + a(attributes) + img.icon(src=icon) + block + else + span(attributes) + img.icon(src=icon) + block + +ul + +item('contact') Contact + +item(href='/contact') Contact diff --git a/node_modules/mocha/node_modules/jade/testing/index.js b/node_modules/mocha/node_modules/jade/testing/index.js new file mode 100644 index 0000000..226e8c0 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/testing/index.js @@ -0,0 +1,11 @@ + +/** + * Module dependencies. + */ + +var jade = require('../'); + +jade.renderFile('testing/index.jade', { pretty: true, debug: true, compileDebug: false }, function(err, str){ + if (err) throw err; + console.log(str); +}); \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/testing/layout.jade b/node_modules/mocha/node_modules/jade/testing/layout.jade new file mode 100644 index 0000000..6923cf1 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/testing/layout.jade @@ -0,0 +1,6 @@ +html + include head + script(src='/caustic.js') + script(src='/app.js') + body + block content \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/testing/user.jade b/node_modules/mocha/node_modules/jade/testing/user.jade new file mode 100644 index 0000000..3c636b7 --- /dev/null +++ b/node_modules/mocha/node_modules/jade/testing/user.jade @@ -0,0 +1,7 @@ +h1 Tobi +p Is a ferret + +ul + li: a foo + li: a bar + li: a baz \ No newline at end of file diff --git a/node_modules/mocha/node_modules/jade/testing/user.js b/node_modules/mocha/node_modules/jade/testing/user.js new file mode 100644 index 0000000..2ecc45e --- /dev/null +++ b/node_modules/mocha/node_modules/jade/testing/user.js @@ -0,0 +1,27 @@ +function anonymous(locals, attrs, escape, rethrow) { +var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow; +var __jade = [{ lineno: 1, filename: "testing/user.jade" }]; +try { +var buf = []; +with (locals || {}) { +var interp; +__jade.unshift({ lineno: 1, filename: __jade[0].filename }); +__jade.unshift({ lineno: 1, filename: __jade[0].filename }); +buf.push('

    Tobi'); +__jade.unshift({ lineno: undefined, filename: __jade[0].filename }); +__jade.shift(); +buf.push('

    '); +__jade.shift(); +__jade.unshift({ lineno: 2, filename: __jade[0].filename }); +buf.push('

    Is a ferret'); +__jade.unshift({ lineno: undefined, filename: __jade[0].filename }); +__jade.shift(); +buf.push('

    '); +__jade.shift(); +__jade.shift(); +} +return buf.join(""); +} catch (err) { + rethrow(err, __jade[0].filename, __jade[0].lineno); +} +} \ No newline at end of file diff --git a/node_modules/mocha/node_modules/mkdirp/.travis.yml b/node_modules/mocha/node_modules/mkdirp/.travis.yml new file mode 100644 index 0000000..74c57bf --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/.travis.yml @@ -0,0 +1,8 @@ +language: node_js +node_js: + - "0.8" + - "0.10" + - "0.12" + - "iojs" +before_install: + - npm install -g npm@~1.4.6 diff --git a/node_modules/mocha/node_modules/mkdirp/LICENSE b/node_modules/mocha/node_modules/mkdirp/LICENSE new file mode 100644 index 0000000..432d1ae --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright 2010 James Halliday (mail@substack.net) + +This project is free software released under the MIT/X11 license: + +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. diff --git a/node_modules/mocha/node_modules/mkdirp/bin/cmd.js b/node_modules/mocha/node_modules/mkdirp/bin/cmd.js new file mode 100755 index 0000000..d95de15 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/bin/cmd.js @@ -0,0 +1,33 @@ +#!/usr/bin/env node + +var mkdirp = require('../'); +var minimist = require('minimist'); +var fs = require('fs'); + +var argv = minimist(process.argv.slice(2), { + alias: { m: 'mode', h: 'help' }, + string: [ 'mode' ] +}); +if (argv.help) { + fs.createReadStream(__dirname + '/usage.txt').pipe(process.stdout); + return; +} + +var paths = argv._.slice(); +var mode = argv.mode ? parseInt(argv.mode, 8) : undefined; + +(function next () { + if (paths.length === 0) return; + var p = paths.shift(); + + if (mode === undefined) mkdirp(p, cb) + else mkdirp(p, mode, cb) + + function cb (err) { + if (err) { + console.error(err.message); + process.exit(1); + } + else next(); + } +})(); diff --git a/node_modules/mocha/node_modules/mkdirp/bin/usage.txt b/node_modules/mocha/node_modules/mkdirp/bin/usage.txt new file mode 100644 index 0000000..f952aa2 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/bin/usage.txt @@ -0,0 +1,12 @@ +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories that + don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m, --mode If a directory needs to be created, set the mode as an octal + permission string. + diff --git a/node_modules/mocha/node_modules/mkdirp/examples/pow.js b/node_modules/mocha/node_modules/mkdirp/examples/pow.js new file mode 100644 index 0000000..e692421 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/examples/pow.js @@ -0,0 +1,6 @@ +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); diff --git a/node_modules/mocha/node_modules/mkdirp/index.js b/node_modules/mocha/node_modules/mkdirp/index.js new file mode 100644 index 0000000..6ce241b --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/index.js @@ -0,0 +1,98 @@ +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; + + p = path.resolve(p); + + 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; + + // 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; + } + } + + return made; +}; diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/.travis.yml b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/.travis.yml new file mode 100644 index 0000000..cc4dba2 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - "0.8" + - "0.10" diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/LICENSE b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/LICENSE new file mode 100644 index 0000000..ee27ba4 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/LICENSE @@ -0,0 +1,18 @@ +This software is released under the MIT license: + +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. diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/example/parse.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/example/parse.js new file mode 100644 index 0000000..abff3e8 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/example/parse.js @@ -0,0 +1,2 @@ +var argv = require('../')(process.argv.slice(2)); +console.dir(argv); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/index.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/index.js new file mode 100644 index 0000000..584f551 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/index.js @@ -0,0 +1,187 @@ +module.exports = function (args, opts) { + if (!opts) opts = {}; + + var flags = { bools : {}, strings : {} }; + + [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { + flags.bools[key] = true; + }); + + [].concat(opts.string).filter(Boolean).forEach(function (key) { + flags.strings[key] = true; + }); + + var aliases = {}; + Object.keys(opts.alias || {}).forEach(function (key) { + aliases[key] = [].concat(opts.alias[key]); + aliases[key].forEach(function (x) { + aliases[x] = [key].concat(aliases[key].filter(function (y) { + return x !== y; + })); + }); + }); + + var defaults = opts['default'] || {}; + + var argv = { _ : [] }; + Object.keys(flags.bools).forEach(function (key) { + setArg(key, defaults[key] === undefined ? false : defaults[key]); + }); + + var notFlags = []; + + if (args.indexOf('--') !== -1) { + notFlags = args.slice(args.indexOf('--')+1); + args = args.slice(0, args.indexOf('--')); + } + + function setArg (key, val) { + var value = !flags.strings[key] && isNumber(val) + ? Number(val) : val + ; + setKey(argv, key.split('.'), value); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), value); + }); + } + + for (var i = 0; i < args.length; i++) { + var arg = args[i]; + + if (/^--.+=/.test(arg)) { + // Using [\s\S] instead of . because js doesn't support the + // 'dotall' regex modifier. See: + // http://stackoverflow.com/a/1068308/13216 + var m = arg.match(/^--([^=]+)=([\s\S]*)$/); + setArg(m[1], m[2]); + } + else if (/^--no-.+/.test(arg)) { + var key = arg.match(/^--no-(.+)/)[1]; + setArg(key, false); + } + else if (/^--.+/.test(arg)) { + var key = arg.match(/^--(.+)/)[1]; + var next = args[i + 1]; + if (next !== undefined && !/^-/.test(next) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, next); + i++; + } + else if (/^(true|false)$/.test(next)) { + setArg(key, next === 'true'); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true); + } + } + else if (/^-[^-]+/.test(arg)) { + var letters = arg.slice(1,-1).split(''); + + var broken = false; + for (var j = 0; j < letters.length; j++) { + var next = arg.slice(j+2); + + if (next === '-') { + setArg(letters[j], next) + continue; + } + + if (/[A-Za-z]/.test(letters[j]) + && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { + setArg(letters[j], next); + broken = true; + break; + } + + if (letters[j+1] && letters[j+1].match(/\W/)) { + setArg(letters[j], arg.slice(j+2)); + broken = true; + break; + } + else { + setArg(letters[j], flags.strings[letters[j]] ? '' : true); + } + } + + var key = arg.slice(-1)[0]; + if (!broken && key !== '-') { + if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) + && !flags.bools[key] + && (aliases[key] ? !flags.bools[aliases[key]] : true)) { + setArg(key, args[i+1]); + i++; + } + else if (args[i+1] && /true|false/.test(args[i+1])) { + setArg(key, args[i+1] === 'true'); + i++; + } + else { + setArg(key, flags.strings[key] ? '' : true); + } + } + } + else { + argv._.push( + flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) + ); + } + } + + Object.keys(defaults).forEach(function (key) { + if (!hasKey(argv, key.split('.'))) { + setKey(argv, key.split('.'), defaults[key]); + + (aliases[key] || []).forEach(function (x) { + setKey(argv, x.split('.'), defaults[key]); + }); + } + }); + + notFlags.forEach(function(key) { + argv._.push(key); + }); + + return argv; +}; + +function hasKey (obj, keys) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + o = (o[key] || {}); + }); + + var key = keys[keys.length - 1]; + return key in o; +} + +function setKey (obj, keys, value) { + var o = obj; + keys.slice(0,-1).forEach(function (key) { + if (o[key] === undefined) o[key] = {}; + o = o[key]; + }); + + var key = keys[keys.length - 1]; + if (o[key] === undefined || typeof o[key] === 'boolean') { + o[key] = value; + } + else if (Array.isArray(o[key])) { + o[key].push(value); + } + else { + o[key] = [ o[key], value ]; + } +} + +function isNumber (x) { + if (typeof x === 'number') return true; + if (/^0x[0-9a-f]+$/i.test(x)) return true; + return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); +} + +function longest (xs) { + return Math.max.apply(null, xs.map(function (x) { return x.length })); +} diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/package.json b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/package.json new file mode 100644 index 0000000..0c9af0e --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/package.json @@ -0,0 +1,67 @@ +{ + "name": "minimist", + "version": "0.0.8", + "description": "parse argument options", + "main": "index.js", + "devDependencies": { + "tape": "~1.0.4", + "tap": "~0.4.0" + }, + "scripts": { + "test": "tap test/*.js" + }, + "testling": { + "files": "test/*.js", + "browsers": [ + "ie/6..latest", + "ff/5", + "firefox/latest", + "chrome/10", + "chrome/latest", + "safari/5.1", + "safari/latest", + "opera/12" + ] + }, + "repository": { + "type": "git", + "url": "git://github.com/substack/minimist.git" + }, + "homepage": "https://github.com/substack/minimist", + "keywords": [ + "argv", + "getopt", + "parser", + "optimist" + ], + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/substack/minimist/issues" + }, + "_id": "minimist@0.0.8", + "dist": { + "shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d", + "tarball": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + }, + "_from": "minimist@0.0.8", + "_npmVersion": "1.4.3", + "_npmUser": { + "name": "substack", + "email": "mail@substack.net" + }, + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "directories": {}, + "_shasum": "857fcabfc3397d2625b8228262e86aa7a011b05d", + "_resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/readme.markdown b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/readme.markdown new file mode 100644 index 0000000..c256353 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/readme.markdown @@ -0,0 +1,73 @@ +# minimist + +parse argument options + +This module is the guts of optimist's argument parser without all the +fanciful decoration. + +[![browser support](https://ci.testling.com/substack/minimist.png)](http://ci.testling.com/substack/minimist) + +[![build status](https://secure.travis-ci.org/substack/minimist.png)](http://travis-ci.org/substack/minimist) + +# example + +``` js +var argv = require('minimist')(process.argv.slice(2)); +console.dir(argv); +``` + +``` +$ node example/parse.js -a beep -b boop +{ _: [], a: 'beep', b: 'boop' } +``` + +``` +$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz +{ _: [ 'foo', 'bar', 'baz' ], + x: 3, + y: 4, + n: 5, + a: true, + b: true, + c: true, + beep: 'boop' } +``` + +# methods + +``` js +var parseArgs = require('minimist') +``` + +## var argv = parseArgs(args, opts={}) + +Return an argument object `argv` populated with the array arguments from `args`. + +`argv._` contains all the arguments that didn't have an option associated with +them. + +Numeric-looking arguments will be returned as numbers unless `opts.string` or +`opts.boolean` is set for that argument name. + +Any arguments after `'--'` will not be parsed and will end up in `argv._`. + +options can be: + +* `opts.string` - a string or array of strings argument names to always treat as +strings +* `opts.boolean` - a string or array of strings to always treat as booleans +* `opts.alias` - an object mapping string names to strings or arrays of string +argument names to use as aliases +* `opts.default` - an object mapping string argument names to default values + +# install + +With [npm](https://npmjs.org) do: + +``` +npm install minimist +``` + +# license + +MIT diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dash.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dash.js new file mode 100644 index 0000000..8b034b9 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dash.js @@ -0,0 +1,24 @@ +var parse = require('../'); +var test = require('tape'); + +test('-', function (t) { + t.plan(5); + t.deepEqual(parse([ '-n', '-' ]), { n: '-', _: [] }); + t.deepEqual(parse([ '-' ]), { _: [ '-' ] }); + t.deepEqual(parse([ '-f-' ]), { f: '-', _: [] }); + t.deepEqual( + parse([ '-b', '-' ], { boolean: 'b' }), + { b: true, _: [ '-' ] } + ); + t.deepEqual( + parse([ '-s', '-' ], { string: 's' }), + { s: '-', _: [] } + ); +}); + +test('-a -- b', function (t) { + t.plan(3); + t.deepEqual(parse([ '-a', '--', 'b' ]), { a: true, _: [ 'b' ] }); + t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] }); + t.deepEqual(parse([ '--a', '--', 'b' ]), { a: true, _: [ 'b' ] }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/default_bool.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/default_bool.js new file mode 100644 index 0000000..f0041ee --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/default_bool.js @@ -0,0 +1,20 @@ +var test = require('tape'); +var parse = require('../'); + +test('boolean default true', function (t) { + var argv = parse([], { + boolean: 'sometrue', + default: { sometrue: true } + }); + t.equal(argv.sometrue, true); + t.end(); +}); + +test('boolean default false', function (t) { + var argv = parse([], { + boolean: 'somefalse', + default: { somefalse: false } + }); + t.equal(argv.somefalse, false); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dotted.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dotted.js new file mode 100644 index 0000000..ef0ae34 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/dotted.js @@ -0,0 +1,16 @@ +var parse = require('../'); +var test = require('tape'); + +test('dotted alias', function (t) { + var argv = parse(['--a.b', '22'], {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}}); + t.equal(argv.a.b, 22); + t.equal(argv.aa.bb, 22); + t.end(); +}); + +test('dotted default', function (t) { + var argv = parse('', {default: {'a.b': 11}, alias: {'a.b': 'aa.bb'}}); + t.equal(argv.a.b, 11); + t.equal(argv.aa.bb, 11); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/long.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/long.js new file mode 100644 index 0000000..5d3a1e0 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/long.js @@ -0,0 +1,31 @@ +var test = require('tape'); +var parse = require('../'); + +test('long opts', function (t) { + t.deepEqual( + parse([ '--bool' ]), + { bool : true, _ : [] }, + 'long boolean' + ); + t.deepEqual( + parse([ '--pow', 'xixxle' ]), + { pow : 'xixxle', _ : [] }, + 'long capture sp' + ); + t.deepEqual( + parse([ '--pow=xixxle' ]), + { pow : 'xixxle', _ : [] }, + 'long capture eq' + ); + t.deepEqual( + parse([ '--host', 'localhost', '--port', '555' ]), + { host : 'localhost', port : 555, _ : [] }, + 'long captures sp' + ); + t.deepEqual( + parse([ '--host=localhost', '--port=555' ]), + { host : 'localhost', port : 555, _ : [] }, + 'long captures eq' + ); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse.js new file mode 100644 index 0000000..8a90646 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse.js @@ -0,0 +1,318 @@ +var parse = require('../'); +var test = require('tape'); + +test('parse args', function (t) { + t.deepEqual( + parse([ '--no-moo' ]), + { moo : false, _ : [] }, + 'no' + ); + t.deepEqual( + parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]), + { v : ['a','b','c'], _ : [] }, + 'multi' + ); + t.end(); +}); + +test('comprehensive', function (t) { + t.deepEqual( + parse([ + '--name=meowmers', 'bare', '-cats', 'woo', + '-h', 'awesome', '--multi=quux', + '--key', 'value', + '-b', '--bool', '--no-meep', '--multi=baz', + '--', '--not-a-flag', 'eek' + ]), + { + c : true, + a : true, + t : true, + s : 'woo', + h : 'awesome', + b : true, + bool : true, + key : 'value', + multi : [ 'quux', 'baz' ], + meep : false, + name : 'meowmers', + _ : [ 'bare', '--not-a-flag', 'eek' ] + } + ); + t.end(); +}); + +test('nums', function (t) { + var argv = parse([ + '-x', '1234', + '-y', '5.67', + '-z', '1e7', + '-w', '10f', + '--hex', '0xdeadbeef', + '789' + ]); + t.deepEqual(argv, { + x : 1234, + y : 5.67, + z : 1e7, + w : '10f', + hex : 0xdeadbeef, + _ : [ 789 ] + }); + t.deepEqual(typeof argv.x, 'number'); + t.deepEqual(typeof argv.y, 'number'); + t.deepEqual(typeof argv.z, 'number'); + t.deepEqual(typeof argv.w, 'string'); + t.deepEqual(typeof argv.hex, 'number'); + t.deepEqual(typeof argv._[0], 'number'); + t.end(); +}); + +test('flag boolean', function (t) { + var argv = parse([ '-t', 'moo' ], { boolean: 't' }); + t.deepEqual(argv, { t : true, _ : [ 'moo' ] }); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); +}); + +test('flag boolean value', function (t) { + var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], { + boolean: [ 't', 'verbose' ], + default: { verbose: true } + }); + + t.deepEqual(argv, { + verbose: false, + t: true, + _: ['moo'] + }); + + t.deepEqual(typeof argv.verbose, 'boolean'); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); +}); + +test('flag boolean default false', function (t) { + var argv = parse(['moo'], { + boolean: ['t', 'verbose'], + default: { verbose: false, t: false } + }); + + t.deepEqual(argv, { + verbose: false, + t: false, + _: ['moo'] + }); + + t.deepEqual(typeof argv.verbose, 'boolean'); + t.deepEqual(typeof argv.t, 'boolean'); + t.end(); + +}); + +test('boolean groups', function (t) { + var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], { + boolean: ['x','y','z'] + }); + + t.deepEqual(argv, { + x : true, + y : false, + z : true, + _ : [ 'one', 'two', 'three' ] + }); + + t.deepEqual(typeof argv.x, 'boolean'); + t.deepEqual(typeof argv.y, 'boolean'); + t.deepEqual(typeof argv.z, 'boolean'); + t.end(); +}); + +test('newlines in params' , function (t) { + var args = parse([ '-s', "X\nX" ]) + t.deepEqual(args, { _ : [], s : "X\nX" }); + + // reproduce in bash: + // VALUE="new + // line" + // node program.js --s="$VALUE" + args = parse([ "--s=X\nX" ]) + t.deepEqual(args, { _ : [], s : "X\nX" }); + t.end(); +}); + +test('strings' , function (t) { + var s = parse([ '-s', '0001234' ], { string: 's' }).s; + t.equal(s, '0001234'); + t.equal(typeof s, 'string'); + + var x = parse([ '-x', '56' ], { string: 'x' }).x; + t.equal(x, '56'); + t.equal(typeof x, 'string'); + t.end(); +}); + +test('stringArgs', function (t) { + var s = parse([ ' ', ' ' ], { string: '_' })._; + t.same(s.length, 2); + t.same(typeof s[0], 'string'); + t.same(s[0], ' '); + t.same(typeof s[1], 'string'); + t.same(s[1], ' '); + t.end(); +}); + +test('empty strings', function(t) { + var s = parse([ '-s' ], { string: 's' }).s; + t.equal(s, ''); + t.equal(typeof s, 'string'); + + var str = parse([ '--str' ], { string: 'str' }).str; + t.equal(str, ''); + t.equal(typeof str, 'string'); + + var letters = parse([ '-art' ], { + string: [ 'a', 't' ] + }); + + t.equal(letters.a, ''); + t.equal(letters.r, true); + t.equal(letters.t, ''); + + t.end(); +}); + + +test('slashBreak', function (t) { + t.same( + parse([ '-I/foo/bar/baz' ]), + { I : '/foo/bar/baz', _ : [] } + ); + t.same( + parse([ '-xyz/foo/bar/baz' ]), + { x : true, y : true, z : '/foo/bar/baz', _ : [] } + ); + t.end(); +}); + +test('alias', function (t) { + var argv = parse([ '-f', '11', '--zoom', '55' ], { + alias: { z: 'zoom' } + }); + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.f, 11); + t.end(); +}); + +test('multiAlias', function (t) { + var argv = parse([ '-f', '11', '--zoom', '55' ], { + alias: { z: [ 'zm', 'zoom' ] } + }); + t.equal(argv.zoom, 55); + t.equal(argv.z, argv.zoom); + t.equal(argv.z, argv.zm); + t.equal(argv.f, 11); + t.end(); +}); + +test('nested dotted objects', function (t) { + var argv = parse([ + '--foo.bar', '3', '--foo.baz', '4', + '--foo.quux.quibble', '5', '--foo.quux.o_O', + '--beep.boop' + ]); + + t.same(argv.foo, { + bar : 3, + baz : 4, + quux : { + quibble : 5, + o_O : true + } + }); + t.same(argv.beep, { boop : true }); + t.end(); +}); + +test('boolean and alias with chainable api', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + herp: { alias: 'h', boolean: true } + }; + var aliasedArgv = parse(aliased, { + boolean: 'herp', + alias: { h: 'herp' } + }); + var propertyArgv = parse(regular, { + boolean: 'herp', + alias: { h: 'herp' } + }); + var expected = { + herp: true, + h: true, + '_': [ 'derp' ] + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +test('boolean and alias with options hash', function (t) { + var aliased = [ '-h', 'derp' ]; + var regular = [ '--herp', 'derp' ]; + var opts = { + alias: { 'h': 'herp' }, + boolean: 'herp' + }; + var aliasedArgv = parse(aliased, opts); + var propertyArgv = parse(regular, opts); + var expected = { + herp: true, + h: true, + '_': [ 'derp' ] + }; + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +test('boolean and alias using explicit true', function (t) { + var aliased = [ '-h', 'true' ]; + var regular = [ '--herp', 'true' ]; + var opts = { + alias: { h: 'herp' }, + boolean: 'h' + }; + var aliasedArgv = parse(aliased, opts); + var propertyArgv = parse(regular, opts); + var expected = { + herp: true, + h: true, + '_': [ ] + }; + + t.same(aliasedArgv, expected); + t.same(propertyArgv, expected); + t.end(); +}); + +// regression, see https://github.com/substack/node-optimist/issues/71 +test('boolean and --x=true', function(t) { + var parsed = parse(['--boool', '--other=true'], { + boolean: 'boool' + }); + + t.same(parsed.boool, true); + t.same(parsed.other, 'true'); + + parsed = parse(['--boool', '--other=false'], { + boolean: 'boool' + }); + + t.same(parsed.boool, true); + t.same(parsed.other, 'false'); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js new file mode 100644 index 0000000..21851b0 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/parse_modified.js @@ -0,0 +1,9 @@ +var parse = require('../'); +var test = require('tape'); + +test('parse with modifier functions' , function (t) { + t.plan(1); + + var argv = parse([ '-b', '123' ], { boolean: 'b' }); + t.deepEqual(argv, { b: true, _: ['123'] }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/short.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/short.js new file mode 100644 index 0000000..d513a1c --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/short.js @@ -0,0 +1,67 @@ +var parse = require('../'); +var test = require('tape'); + +test('numeric short args', function (t) { + t.plan(2); + t.deepEqual(parse([ '-n123' ]), { n: 123, _: [] }); + t.deepEqual( + parse([ '-123', '456' ]), + { 1: true, 2: true, 3: 456, _: [] } + ); +}); + +test('short', function (t) { + t.deepEqual( + parse([ '-b' ]), + { b : true, _ : [] }, + 'short boolean' + ); + t.deepEqual( + parse([ 'foo', 'bar', 'baz' ]), + { _ : [ 'foo', 'bar', 'baz' ] }, + 'bare' + ); + t.deepEqual( + parse([ '-cats' ]), + { c : true, a : true, t : true, s : true, _ : [] }, + 'group' + ); + t.deepEqual( + parse([ '-cats', 'meow' ]), + { c : true, a : true, t : true, s : 'meow', _ : [] }, + 'short group next' + ); + t.deepEqual( + parse([ '-h', 'localhost' ]), + { h : 'localhost', _ : [] }, + 'short capture' + ); + t.deepEqual( + parse([ '-h', 'localhost', '-p', '555' ]), + { h : 'localhost', p : 555, _ : [] }, + 'short captures' + ); + t.end(); +}); + +test('mixed short bool and capture', function (t) { + t.same( + parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ] + } + ); + t.end(); +}); + +test('short and long', function (t) { + t.deepEqual( + parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]), + { + f : true, p : 555, h : 'localhost', + _ : [ 'script.js' ] + } + ); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/whitespace.js b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/whitespace.js new file mode 100644 index 0000000..8a52a58 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/node_modules/minimist/test/whitespace.js @@ -0,0 +1,8 @@ +var parse = require('../'); +var test = require('tape'); + +test('whitespace should be whitespace' , function (t) { + t.plan(1); + var x = parse([ '-x', '\t' ]).x; + t.equal(x, '\t'); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/package.json b/node_modules/mocha/node_modules/mkdirp/package.json new file mode 100644 index 0000000..0638efa --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/package.json @@ -0,0 +1,60 @@ +{ + "name": "mkdirp", + "description": "Recursively mkdir, like `mkdir -p`", + "version": "0.5.1", + "author": { + "name": "James Halliday", + "email": "mail@substack.net", + "url": "http://substack.net" + }, + "main": "index.js", + "keywords": [ + "mkdir", + "directory" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/substack/node-mkdirp.git" + }, + "scripts": { + "test": "tap test/*.js" + }, + "dependencies": { + "minimist": "0.0.8" + }, + "devDependencies": { + "tap": "1", + "mock-fs": "2 >=2.7.0" + }, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "license": "MIT", + "gitHead": "d4eff0f06093aed4f387e88e9fc301cb76beedc7", + "bugs": { + "url": "https://github.com/substack/node-mkdirp/issues" + }, + "homepage": "https://github.com/substack/node-mkdirp#readme", + "_id": "mkdirp@0.5.1", + "_shasum": "30057438eac6cf7f8c4767f38648d6697d75c903", + "_from": "mkdirp@0.5.1", + "_npmVersion": "2.9.0", + "_nodeVersion": "2.0.0", + "_npmUser": { + "name": "substack", + "email": "substack@gmail.com" + }, + "dist": { + "shasum": "30057438eac6cf7f8c4767f38648d6697d75c903", + "tarball": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" + }, + "maintainers": [ + { + "name": "substack", + "email": "mail@substack.net" + } + ], + "directories": {}, + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mocha/node_modules/mkdirp/readme.markdown b/node_modules/mocha/node_modules/mkdirp/readme.markdown new file mode 100644 index 0000000..3cc1315 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/readme.markdown @@ -0,0 +1,100 @@ +# mkdirp + +Like `mkdir -p`, but in node.js! + +[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp) + +# example + +## pow.js + +```js +var mkdirp = require('mkdirp'); + +mkdirp('/tmp/foo/bar/baz', function (err) { + if (err) console.error(err) + else console.log('pow!') +}); +``` + +Output + +``` +pow! +``` + +And now /tmp/foo/bar/baz exists, huzzah! + +# methods + +```js +var mkdirp = require('mkdirp'); +``` + +## mkdirp(dir, opts, cb) + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `opts.mode`. If `opts` is a non-object, it will be treated as +the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +`cb(err, made)` fires with the error or the first directory `made` +that had to be created, if any. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdir(path, mode, cb)` and +`opts.fs.stat(path, cb)`. + +## mkdirp.sync(dir, opts) + +Synchronously create a new directory and any necessary subdirectories at `dir` +with octal permission string `opts.mode`. If `opts` is a non-object, it will be +treated as the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0777 & (~process.umask())`. + +Returns the first directory that had to be created, if any. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` and +`opts.fs.statSync(path)`. + +# usage + +This package also ships with a `mkdirp` command. + +``` +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories that + don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m, --mode If a directory needs to be created, set the mode as an octal + permission string. + +``` + +# install + +With [npm](http://npmjs.org) do: + +``` +npm install mkdirp +``` + +to get the library, or + +``` +npm install -g mkdirp +``` + +to get the command. + +# license + +MIT diff --git a/node_modules/mocha/node_modules/mkdirp/test/chmod.js b/node_modules/mocha/node_modules/mkdirp/test/chmod.js new file mode 100644 index 0000000..6a404b9 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/chmod.js @@ -0,0 +1,41 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); +var _0744 = parseInt('0744', 8); + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +test('chmod-pre', function (t) { + var mode = _0744 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.equal(stat && stat.mode & _0777, mode, 'should be 0744'); + t.end(); + }); + }); +}); + +test('chmod', function (t) { + var mode = _0755 + mkdirp(file, mode, function (er) { + t.ifError(er, 'should not error'); + fs.stat(file, function (er, stat) { + t.ifError(er, 'should exist'); + t.ok(stat && stat.isDirectory(), 'should be directory'); + t.end(); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/clobber.js b/node_modules/mocha/node_modules/mkdirp/test/clobber.js new file mode 100644 index 0000000..2433b9a --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/clobber.js @@ -0,0 +1,38 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; +var _0755 = parseInt('0755', 8); + +var ps = [ '', 'tmp' ]; + +for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); +} + +var file = ps.join('/'); + +// a file in the way +var itw = ps.slice(0, 3).join('/'); + + +test('clobber-pre', function (t) { + console.error("about to write to "+itw) + fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.'); + + fs.stat(itw, function (er, stat) { + t.ifError(er) + t.ok(stat && stat.isFile(), 'should be file') + t.end() + }) +}) + +test('clobber', function (t) { + t.plan(2); + mkdirp(file, _0755, function (err) { + t.ok(err); + t.equal(err.code, 'ENOTDIR'); + t.end(); + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/mkdirp.js b/node_modules/mocha/node_modules/mkdirp/test/mkdirp.js new file mode 100644 index 0000000..eaa8921 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/mkdirp.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('woo', function (t) { + t.plan(5); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, _0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }) + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/opts_fs.js b/node_modules/mocha/node_modules/mkdirp/test/opts_fs.js new file mode 100644 index 0000000..97186b6 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/opts_fs.js @@ -0,0 +1,29 @@ +var mkdirp = require('../'); +var path = require('path'); +var test = require('tap').test; +var mockfs = require('mock-fs'); +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('opts.fs', function (t) { + t.plan(5); + + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/beep/boop/' + [x,y,z].join('/'); + var xfs = mockfs.fs(); + + mkdirp(file, { fs: xfs, mode: _0755 }, function (err) { + t.ifError(err); + xfs.exists(file, function (ex) { + t.ok(ex, 'created file'); + xfs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/opts_fs_sync.js b/node_modules/mocha/node_modules/mkdirp/test/opts_fs_sync.js new file mode 100644 index 0000000..6c370aa --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/opts_fs_sync.js @@ -0,0 +1,27 @@ +var mkdirp = require('../'); +var path = require('path'); +var test = require('tap').test; +var mockfs = require('mock-fs'); +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('opts.fs sync', function (t) { + t.plan(4); + + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/beep/boop/' + [x,y,z].join('/'); + var xfs = mockfs.fs(); + + mkdirp.sync(file, { fs: xfs, mode: _0755 }); + xfs.exists(file, function (ex) { + t.ok(ex, 'created file'); + xfs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/perm.js b/node_modules/mocha/node_modules/mkdirp/test/perm.js new file mode 100644 index 0000000..fbce44b --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/perm.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('async perm', function (t) { + t.plan(5); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16); + + mkdirp(file, _0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }) + }); +}); + +test('async root perm', function (t) { + mkdirp('/tmp', _0755, function (err) { + if (err) t.fail(err); + t.end(); + }); + t.end(); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/perm_sync.js b/node_modules/mocha/node_modules/mkdirp/test/perm_sync.js new file mode 100644 index 0000000..398229f --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/perm_sync.js @@ -0,0 +1,36 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('sync perm', function (t) { + t.plan(4); + var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json'; + + mkdirp.sync(file, _0755); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); + +test('sync root perm', function (t) { + t.plan(3); + + var file = '/tmp'; + mkdirp.sync(file, _0755); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/race.js b/node_modules/mocha/node_modules/mkdirp/test/race.js new file mode 100644 index 0000000..b0b9e18 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/race.js @@ -0,0 +1,37 @@ +var mkdirp = require('../').mkdirp; +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('race', function (t) { + t.plan(10); + var ps = [ '', 'tmp' ]; + + for (var i = 0; i < 25; i++) { + var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + ps.push(dir); + } + var file = ps.join('/'); + + var res = 2; + mk(file); + + mk(file); + + function mk (file, cb) { + mkdirp(file, _0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }) + }); + } +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/rel.js b/node_modules/mocha/node_modules/mkdirp/test/rel.js new file mode 100644 index 0000000..4ddb342 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/rel.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('rel', function (t) { + t.plan(5); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var cwd = process.cwd(); + process.chdir('/tmp'); + + var file = [x,y,z].join('/'); + + mkdirp(file, _0755, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + process.chdir(cwd); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }) + }) + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/return.js b/node_modules/mocha/node_modules/mkdirp/test/return.js new file mode 100644 index 0000000..bce68e5 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/return.js @@ -0,0 +1,25 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, '/tmp/' + x); + mkdirp(file, function (err, made) { + t.ifError(err); + t.equal(made, null); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/return_sync.js b/node_modules/mocha/node_modules/mkdirp/test/return_sync.js new file mode 100644 index 0000000..7c222d3 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/return_sync.js @@ -0,0 +1,24 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; + +test('return value', function (t) { + t.plan(2); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + // should return the first dir created. + // By this point, it would be profoundly surprising if /tmp didn't + // already exist, since every other test makes things in there. + // Note that this will throw on failure, which will fail the test. + var made = mkdirp.sync(file); + t.equal(made, '/tmp/' + x); + + // making the same file again should have no effect. + made = mkdirp.sync(file); + t.equal(made, null); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/root.js b/node_modules/mocha/node_modules/mkdirp/test/root.js new file mode 100644 index 0000000..9e7d079 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/root.js @@ -0,0 +1,19 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var test = require('tap').test; +var _0755 = parseInt('0755', 8); + +test('root', function (t) { + // '/' on unix, 'c:/' on windows. + var file = path.resolve('/'); + + mkdirp(file, _0755, function (err) { + if (err) throw err + fs.stat(file, function (er, stat) { + if (er) throw er + t.ok(stat.isDirectory(), 'target is a directory'); + t.end(); + }) + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/sync.js b/node_modules/mocha/node_modules/mkdirp/test/sync.js new file mode 100644 index 0000000..8c8dc93 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('sync', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file, _0755); + } catch (err) { + t.fail(err); + return t.end(); + } + + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0755); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/umask.js b/node_modules/mocha/node_modules/mkdirp/test/umask.js new file mode 100644 index 0000000..2033c63 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/umask.js @@ -0,0 +1,28 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('implicit mode from umask', function (t) { + t.plan(5); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + mkdirp(file, function (err) { + t.ifError(err); + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, _0777 & (~process.umask())); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }) + }); +}); diff --git a/node_modules/mocha/node_modules/mkdirp/test/umask_sync.js b/node_modules/mocha/node_modules/mkdirp/test/umask_sync.js new file mode 100644 index 0000000..11a7614 --- /dev/null +++ b/node_modules/mocha/node_modules/mkdirp/test/umask_sync.js @@ -0,0 +1,32 @@ +var mkdirp = require('../'); +var path = require('path'); +var fs = require('fs'); +var exists = fs.exists || path.exists; +var test = require('tap').test; +var _0777 = parseInt('0777', 8); +var _0755 = parseInt('0755', 8); + +test('umask sync modes', function (t) { + t.plan(4); + var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16); + + var file = '/tmp/' + [x,y,z].join('/'); + + try { + mkdirp.sync(file); + } catch (err) { + t.fail(err); + return t.end(); + } + + exists(file, function (ex) { + t.ok(ex, 'file created'); + fs.stat(file, function (err, stat) { + t.ifError(err); + t.equal(stat.mode & _0777, (_0777 & (~process.umask()))); + t.ok(stat.isDirectory(), 'target not a directory'); + }); + }); +}); diff --git a/node_modules/mocha/node_modules/supports-color/cli.js b/node_modules/mocha/node_modules/supports-color/cli.js new file mode 100755 index 0000000..e746987 --- /dev/null +++ b/node_modules/mocha/node_modules/supports-color/cli.js @@ -0,0 +1,29 @@ +#!/usr/bin/env node +'use strict'; +var pkg = require('./package.json'); +var supportsColor = require('./'); +var argv = process.argv.slice(2); + +function help() { + console.log([ + '', + ' ' + pkg.description, + '', + ' Usage', + ' supports-color', + '', + ' Exits with code 0 if color is supported and 1 if not' + ].join('\n')); +} + +if (argv.indexOf('--help') !== -1) { + help(); + return; +} + +if (argv.indexOf('--version') !== -1) { + console.log(pkg.version); + return; +} + +process.exit(supportsColor ? 0 : 1); diff --git a/node_modules/mocha/node_modules/supports-color/index.js b/node_modules/mocha/node_modules/supports-color/index.js new file mode 100644 index 0000000..a2b9784 --- /dev/null +++ b/node_modules/mocha/node_modules/supports-color/index.js @@ -0,0 +1,39 @@ +'use strict'; +var argv = process.argv; + +module.exports = (function () { + if (argv.indexOf('--no-color') !== -1 || + argv.indexOf('--no-colors') !== -1 || + argv.indexOf('--color=false') !== -1) { + return false; + } + + if (argv.indexOf('--color') !== -1 || + argv.indexOf('--colors') !== -1 || + argv.indexOf('--color=true') !== -1 || + argv.indexOf('--color=always') !== -1) { + return true; + } + + if (process.stdout && !process.stdout.isTTY) { + return false; + } + + if (process.platform === 'win32') { + return true; + } + + if ('COLORTERM' in process.env) { + return true; + } + + if (process.env.TERM === 'dumb') { + return false; + } + + if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) { + return true; + } + + return false; +})(); diff --git a/node_modules/mocha/node_modules/supports-color/package.json b/node_modules/mocha/node_modules/supports-color/package.json new file mode 100644 index 0000000..20a97bb --- /dev/null +++ b/node_modules/mocha/node_modules/supports-color/package.json @@ -0,0 +1,85 @@ +{ + "name": "supports-color", + "version": "1.2.0", + "description": "Detect whether a terminal supports color", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/supports-color.git" + }, + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "http://sindresorhus.com" + }, + "bin": { + "supports-color": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + }, + "scripts": { + "test": "mocha" + }, + "files": [ + "index.js", + "cli.js" + ], + "keywords": [ + "cli", + "bin", + "color", + "colour", + "colors", + "terminal", + "console", + "cli", + "ansi", + "styles", + "tty", + "rgb", + "256", + "shell", + "xterm", + "command-line", + "support", + "supports", + "capability", + "detect" + ], + "devDependencies": { + "mocha": "*", + "require-uncached": "^1.0.2" + }, + "gitHead": "e1815a472ebb59612e485096ae31a394e47d3c93", + "bugs": { + "url": "https://github.com/sindresorhus/supports-color/issues" + }, + "homepage": "https://github.com/sindresorhus/supports-color", + "_id": "supports-color@1.2.0", + "_shasum": "ff1ed1e61169d06b3cf2d588e188b18d8847e17e", + "_from": "supports-color@1.2.0", + "_npmVersion": "2.1.2", + "_nodeVersion": "0.10.32", + "_npmUser": { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + "maintainers": [ + { + "name": "sindresorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "jbnicolai", + "email": "jappelman@xebia.com" + } + ], + "dist": { + "shasum": "ff1ed1e61169d06b3cf2d588e188b18d8847e17e", + "tarball": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mocha/node_modules/supports-color/readme.md b/node_modules/mocha/node_modules/supports-color/readme.md new file mode 100644 index 0000000..32d4f46 --- /dev/null +++ b/node_modules/mocha/node_modules/supports-color/readme.md @@ -0,0 +1,44 @@ +# supports-color [![Build Status](https://travis-ci.org/sindresorhus/supports-color.svg?branch=master)](https://travis-ci.org/sindresorhus/supports-color) + +> Detect whether a terminal supports color + + +## Install + +```sh +$ npm install --save supports-color +``` + + +## Usage + +```js +var supportsColor = require('supports-color'); + +if (supportsColor) { + console.log('Terminal supports color'); +} +``` + +It obeys the `--color` and `--no-color` CLI flags. + + +## CLI + +```sh +$ npm install --global supports-color +``` + +``` +$ supports-color --help + + Usage + supports-color + + Exits with code 0 if color is supported and 1 if not +``` + + +## License + +MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/node_modules/mocha/node_modules/to-iso-string/.npmignore b/node_modules/mocha/node_modules/to-iso-string/.npmignore new file mode 100644 index 0000000..665aa21 --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/.npmignore @@ -0,0 +1,3 @@ +components +build +node_modules diff --git a/node_modules/mocha/node_modules/to-iso-string/History.md b/node_modules/mocha/node_modules/to-iso-string/History.md new file mode 100644 index 0000000..f23b31e --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/History.md @@ -0,0 +1,9 @@ + +0.0.2 - May 12, 2015 +-------------------- + +- Fix npm publish issue + +0.0.1 - October 16, 2013 +------------------------ +:sparkles: diff --git a/node_modules/mocha/node_modules/to-iso-string/Makefile b/node_modules/mocha/node_modules/to-iso-string/Makefile new file mode 100644 index 0000000..9600296 --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/Makefile @@ -0,0 +1,17 @@ + +build: components node_modules + @component build --dev + +clean: + @rm -rf components build node_modules + +components: component.json + @component install --dev + +node_modules: package.json + @npm install + +test: build + @./node_modules/.bin/mocha --reporter spec + +.PHONY: clean test \ No newline at end of file diff --git a/node_modules/mocha/node_modules/to-iso-string/Readme.md b/node_modules/mocha/node_modules/to-iso-string/Readme.md new file mode 100644 index 0000000..905b8d6 --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/Readme.md @@ -0,0 +1,18 @@ + +# to-iso-string + + Cross-browser toISOString support. + +## Example + +```js +var iso = require('to-iso-string'); +var date = new Date("05 October 2011 14:48 UTC"); + +iso(date); +// "2011-10-05T14:48:00.000Z" +``` + +## License + + MIT \ No newline at end of file diff --git a/node_modules/mocha/node_modules/to-iso-string/component.json b/node_modules/mocha/node_modules/to-iso-string/component.json new file mode 100644 index 0000000..f5270b5 --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/component.json @@ -0,0 +1,9 @@ +{ + "name": "to-iso-string", + "repo": "segmentio/to-iso-string", + "version": "0.0.2", + "license": "MIT", + "description": "Cross-browser toISOString support.", + "keywords": ["iso", "format", "iso8601", "date", "isostring", "toISOString"], + "scripts": ["index.js"] +} diff --git a/node_modules/mocha/node_modules/to-iso-string/index.js b/node_modules/mocha/node_modules/to-iso-string/index.js new file mode 100644 index 0000000..4675691 --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/index.js @@ -0,0 +1,40 @@ + +/** + * 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; +} \ No newline at end of file diff --git a/node_modules/mocha/node_modules/to-iso-string/package.json b/node_modules/mocha/node_modules/to-iso-string/package.json new file mode 100644 index 0000000..15ca77e --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/package.json @@ -0,0 +1,50 @@ +{ + "name": "to-iso-string", + "repository": { + "type": "git", + "url": "git://github.com/segmentio/to-iso-string.git" + }, + "version": "0.0.2", + "license": "MIT", + "description": "Cross-browser toISOString support.", + "keywords": [ + "iso", + "format", + "iso8601", + "date", + "isostring", + "toISOString" + ], + "devDependencies": { + "mocha": "*" + }, + "gitHead": "dded50dbad7ad7568dfaf38e7fe623e43977837d", + "bugs": { + "url": "https://github.com/segmentio/to-iso-string/issues" + }, + "homepage": "https://github.com/segmentio/to-iso-string#readme", + "_id": "to-iso-string@0.0.2", + "scripts": {}, + "_shasum": "4dc19e664dfccbe25bd8db508b00c6da158255d1", + "_from": "to-iso-string@0.0.2", + "_npmVersion": "2.9.0", + "_nodeVersion": "2.0.1", + "_npmUser": { + "name": "ndhoule", + "email": "nathan@nathanhoule.com" + }, + "dist": { + "shasum": "4dc19e664dfccbe25bd8db508b00c6da158255d1", + "tarball": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz" + }, + "maintainers": [ + { + "name": "ndhoule", + "email": "nathan@nathanhoule.com" + } + ], + "deprecated": "to-iso-string has been deprecated, use @segment/to-iso-string instead.", + "directories": {}, + "_resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/mocha/node_modules/to-iso-string/test/index.js b/node_modules/mocha/node_modules/to-iso-string/test/index.js new file mode 100644 index 0000000..11456b3 --- /dev/null +++ b/node_modules/mocha/node_modules/to-iso-string/test/index.js @@ -0,0 +1,10 @@ + +var assert = require('assert'); +var iso = require('..'); + +describe('to-iso-string', function () { + it('should work', function () { + var date = new Date("05 October 2011 14:48 UTC"); + assert('2011-10-05T14:48:00.000Z' == iso(date)); + }); +}); \ No newline at end of file diff --git a/node_modules/mocha/package.json b/node_modules/mocha/package.json new file mode 100644 index 0000000..8e148b9 --- /dev/null +++ b/node_modules/mocha/package.json @@ -0,0 +1,1281 @@ +{ + "name": "mocha", + "version": "2.5.3", + "description": "simple, flexible, fun test framework", + "keywords": [ + "mocha", + "test", + "bdd", + "tdd", + "tap" + ], + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "contributors": [ + { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + { + "name": "Travis Jeffery", + "email": "tj@travisjeffery.com" + }, + { + "name": "Christopher Hiller", + "email": "boneskull@boneskull.com" + }, + { + "name": "Daniel St. Jules", + "email": "danielst.jules@gmail.com" + }, + { + "name": "Joshua Appelman", + "email": "jappelman@xebia.com" + }, + { + "name": "David da Silva Contín", + "email": "dasilvacontin@gmail.com" + }, + { + "name": "Guillermo Rauch", + "email": "rauchg@gmail.com" + }, + { + "name": "Ariel Mashraki", + "email": "ariel@mashraki.co.il" + }, + { + "name": "Attila Domokos", + "email": "adomokos@gmail.com" + }, + { + "name": "John Firebaugh", + "email": "john.firebaugh@gmail.com" + }, + { + "name": "Jo Liss", + "email": "joliss42@gmail.com" + }, + { + "name": "Nathan Rajlich", + "email": "nathan@tootallnate.net" + }, + { + "name": "Nathan Houle", + "email": "nathan@nathanhoule.com" + }, + { + "name": "Mike Pennisi", + "email": "mike@mikepennisi.com" + }, + { + "name": "James Carr", + "email": "james.r.carr@gmail.com" + }, + { + "name": "Brendan Nee", + "email": "brendan.nee@gmail.com" + }, + { + "name": "Glen Mailer", + "email": "glenjamin@gmail.com" + }, + { + "name": "Mislav Marohnić", + "email": "mislav.marohnic@gmail.com" + }, + { + "name": "Aaron Heckmann", + "email": "aaron.heckmann+github@gmail.com" + }, + { + "name": "Ryunosuke SATO", + "email": "tricknotes.rs@gmail.com" + }, + { + "name": "Jonathan Ong", + "email": "jonathanrichardong@gmail.com" + }, + { + "name": "Joshua Krall", + "email": "joshuakrall@pobox.com" + }, + { + "name": "Maximilian Antoni", + "email": "mail@maxantoni.de" + }, + { + "name": "hokaccha", + "email": "k.hokamura@gmail.com" + }, + { + "name": "Domenic Denicola", + "email": "domenic@domenicdenicola.com" + }, + { + "name": "Forbes Lindesay", + "email": "forbes@lindesay.co.uk" + }, + { + "name": "Raynos", + "email": "raynos2@gmail.com" + }, + { + "name": "Xavier Antoviaque", + "email": "xavier@antoviaque.org" + }, + { + "name": "Andreas Lind Petersen", + "email": "andreas@one.com" + }, + { + "name": "Ben Lindsey", + "email": "ben.lindsey@vungle.com" + }, + { + "name": "Mathieu Desvé", + "email": "mathieudesve@MacBook-Pro-de-Mathieu.local" + }, + { + "name": "Fredrik Enestad", + "email": "fredrik@devloop.se" + }, + { + "name": "Rico Sta. Cruz", + "email": "rstacruz@users.noreply.github.com" + }, + { + "name": "Paul Miller", + "email": "paul@paulmillr.com" + }, + { + "name": "Ben Bradley", + "email": "ben@bradleyit.com" + }, + { + "name": "fool2fish", + "email": "fool2fish@gmail.com" + }, + { + "name": "Cory Thomas", + "email": "cory.thomas@bazaarvoice.com" + }, + { + "name": "Sune Simonsen", + "email": "sune@we-knowhow.dk" + }, + { + "name": "Michael Demmer", + "email": "demmer@jut.io" + }, + { + "name": "Tyson Tate", + "email": "tyson@tysontate.com" + }, + { + "name": "eiji.ienaga", + "email": "eiji.ienaga@gmail.com" + }, + { + "name": "Valentin Agachi", + "email": "github-com@agachi.name" + }, + { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com" + }, + { + "name": "Merrick Christensen", + "email": "merrick.christensen@gmail.com" + }, + { + "name": "Wil Moore III", + "email": "wil.moore@wilmoore.com" + }, + { + "name": "Nathan Bowser", + "email": "nathan.bowser@spiderstrategies.com" + }, + { + "name": "Jesse Dailey", + "email": "jesse.dailey@gmail.com" + }, + { + "name": "Benjie Gillam", + "email": "benjie@jemjie.com" + }, + { + "name": "Vlad Magdalin", + "email": "vlad@webflow.com" + }, + { + "name": "David Henderson", + "email": "david.henderson@triggeredmessaging.com" + }, + { + "name": "Long Ho", + "email": "longho@yahoo-inc.com" + }, + { + "name": "Adam Gruber", + "email": "talknmime@gmail.com" + }, + { + "name": "Sean Lang", + "email": "slang800@gmail.com" + }, + { + "name": "Shawn Krisman", + "email": "telaviv@github" + }, + { + "name": "Simon Gaeremynck", + "email": "gaeremyncks@gmail.com" + }, + { + "name": "John Reeves", + "email": "github@jonnyreeves.co.uk" + }, + { + "name": "Soel", + "email": "shachar.soel@sap.com" + }, + { + "name": "Buck Doyle", + "email": "b@chromatin.ca" + }, + { + "name": "Max Goodman", + "email": "c@chromakode.com" + }, + { + "name": "Jonas Westerlund", + "email": "jonas.westerlund@me.com" + }, + { + "name": "Michael Riley", + "email": "michael.riley@autodesk.com" + }, + { + "name": "Ian Storm Taylor", + "email": "ian@ianstormtaylor.com" + }, + { + "name": "Timo Tijhof", + "email": "krinklemail@gmail.com" + }, + { + "name": "Ian W. Remmel", + "email": "design@ianwremmel.com" + }, + { + "name": "Tobias Bieniek", + "email": "tobias.bieniek@gmail.com" + }, + { + "name": "Arian Stolwijk", + "email": "arian@aryweb.nl" + }, + { + "name": "Nathan Alderson", + "email": "nathan.alderson@adtran.com" + }, + { + "name": "Brian Beck", + "email": "exogen@gmail.com" + }, + { + "name": "Dominique Quatravaux", + "email": "dominique@quatravaux.org" + }, + { + "name": "Xavier Damman", + "email": "xdamman@gmail.com" + }, + { + "name": "Benjamin Eidelman", + "email": "beneidel@gmail.com" + }, + { + "name": "Outsider", + "email": "outsideris@gmail.com" + }, + { + "name": "fcrisci", + "email": "fabio.crisci@amadeus.com" + }, + { + "name": "FARKAS Máté", + "email": "mate.farkas@virtual-call-center.eu" + }, + { + "name": "Parker Moore", + "email": "parkrmoore@gmail.com" + }, + { + "name": "Paul Armstrong", + "email": "paul@paularmstrongdesigns.com" + }, + { + "name": "jsdevel", + "email": "js.developer.undefined@gmail.com" + }, + { + "name": "Justin DuJardin", + "email": "justin.dujardin@sococo.com" + }, + { + "name": "Juzer Ali", + "email": "er.juzerali@gmail.com" + }, + { + "name": "Jacob Wejendorp", + "email": "jacob@wejendorp.dk" + }, + { + "name": "monowerker", + "email": "monowerker@gmail.com" + }, + { + "name": "Alexander Early", + "email": "alexander.early@gmail.com" + }, + { + "name": "Quang Van", + "email": "quangvvv@gmail.com" + }, + { + "name": "Quanlong He", + "email": "kyan.ql.he@gmail.com" + }, + { + "name": "James Nylen", + "email": "jnylen@gmail.com" + }, + { + "name": "Konstantin Käfer", + "email": "github@kkaefer.com" + }, + { + "name": "Jordan Sexton", + "email": "jordan@jordansexton.com" + }, + { + "name": "Josh Lory", + "email": "josh.lory@code.org" + }, + { + "name": "Julien Wajsberg", + "email": "felash@gmail.com" + }, + { + "name": "Jussi Virtanen", + "email": "jussi.k.virtanen@gmail.com" + }, + { + "name": "Jérémie Astori", + "email": "jeremie@astori.fr" + }, + { + "name": "Katie Gengler", + "email": "katiegengler@gmail.com" + }, + { + "name": "Keith Cirkel", + "email": "github@keithcirkel.co.uk" + }, + { + "name": "Kent C. Dodds", + "email": "kent+github@doddsfamily.us" + }, + { + "name": "Kevin Burke", + "email": "kev@inburke.com" + }, + { + "name": "Kevin Conway", + "email": "kevinjacobconway@gmail.com" + }, + { + "name": "Kevin Kirsche", + "email": "Kev.Kirsche+GitHub@gmail.com" + }, + { + "name": "Kirill Korolyov", + "email": "kirill.korolyov@gmail.com" + }, + { + "name": "Koen Punt", + "email": "koen@koenpunt.nl" + }, + { + "name": "Kris Rasmussen", + "email": "kristopher.rasmussen@gmail.com" + }, + { + "name": "Kyle Mitchell", + "email": "kyle@kemitchell.com" + }, + { + "name": "Laszlo Bacsi", + "email": "lackac@lackac.hu" + }, + { + "name": "Liam Newman", + "email": "bitwiseman@gmail.com" + }, + { + "name": "Linus Unnebäck", + "email": "linus@folkdatorn.se" + }, + { + "name": "Maciej Małecki", + "email": "maciej.malecki@notimplemented.org" + }, + { + "name": "Mal Graty", + "email": "mal.graty@googlemail.com" + }, + { + "name": "Marc Kuo", + "email": "kuomarc2@gmail.com" + }, + { + "name": "Marcello Bastea-Forte", + "email": "marcello@cellosoft.com" + }, + { + "name": "Mark Banner", + "email": "standard8@mozilla.com" + }, + { + "name": "Martin Marko", + "email": "marcus@gratex.com" + }, + { + "name": "Matija Marohnić", + "email": "matija.marohnic@gmail.com" + }, + { + "name": "Matt Robenolt", + "email": "matt@ydekproductions.com" + }, + { + "name": "Matt Smith", + "email": "matthewgarysmith@gmail.com" + }, + { + "name": "Matthew Shanley", + "email": "matthewshanley@littlesecretsrecords.com" + }, + { + "name": "Mattias Tidlund", + "email": "mattias.tidlund@learningwell.se" + }, + { + "name": "Michael Jackson", + "email": "mjijackson@gmail.com" + }, + { + "name": "Michael Olson", + "email": "mwolson@member.fsf.org" + }, + { + "name": "Michael Schoonmaker", + "email": "michael.r.schoonmaker@gmail.com" + }, + { + "name": "Michal Charemza", + "email": "michalcharemza@gmail.com" + }, + { + "name": "Moshe Kolodny", + "email": "mkolodny@integralads.com" + }, + { + "name": "Nathan Black", + "email": "nathan@nathanblack.org" + }, + { + "name": "Nick Fitzgerald", + "email": "fitzgen@gmail.com" + }, + { + "name": "Nicolo Taddei", + "email": "taddei.uk@gmail.com" + }, + { + "name": "Noshir Patel", + "email": "nosh@blackpiano.com" + }, + { + "name": "OlegTsyba", + "email": "oleg.tsyba.ua@gmail.com" + }, + { + "name": "Panu Horsmalahti", + "email": "panu.horsmalahti@iki.fi" + }, + { + "name": "Pavel Zubkou", + "email": "pavel.zubkou@gmail.com" + }, + { + "name": "Pete Hawkins", + "email": "pete@petes-imac.frontinternal.net" + }, + { + "name": "Phil Sung", + "email": "psung@dnanexus.com" + }, + { + "name": "Prayag Verma", + "email": "prayag.verma@gmail.com" + }, + { + "name": "R56", + "email": "rviskus@gmail.com" + }, + { + "name": "Refael Ackermann", + "email": "refael@empeeric.com" + }, + { + "name": "Richard Dingwall", + "email": "rdingwall@gmail.com" + }, + { + "name": "Richard Knop", + "email": "RichardKnop@users.noreply.github.com" + }, + { + "name": "Rob Raux", + "email": "rraux@peachworks.com" + }, + { + "name": "Rob Wu", + "email": "rob@robwu.nl" + }, + { + "name": "Robert Rossmann", + "email": "rr.rossmann@me.com" + }, + { + "name": "Romain Prieto", + "email": "romain.prieto@gmail.com" + }, + { + "name": "Roman Neuhauser", + "email": "rneuhauser@suse.cz" + }, + { + "name": "Roman Shtylman", + "email": "shtylman@gmail.com" + }, + { + "name": "Russ Bradberry", + "email": "devdazed@me.com" + }, + { + "name": "Russell Munson", + "email": "rmunson@github.com" + }, + { + "name": "Rustem Mustafin", + "email": "mustafin@kt-labs.com" + }, + { + "name": "Ryan Hubbard", + "email": "ryanmhubbard@gmail.com" + }, + { + "name": "Ryan Shaw", + "email": "ryan.shaw@min.vc" + }, + { + "name": "Salehen Shovon Rahman", + "email": "salehen.rahman@gmail.com" + }, + { + "name": "Sam Mussell", + "email": "smussell@gmail.com" + }, + { + "name": "Sasha Koss", + "email": "koss@nocorp.me" + }, + { + "name": "ScottFreeCode", + "email": "ScottFreeCode@users.noreply.github.com" + }, + { + "name": "Seiya Konno", + "email": "nulltask@gmail.com" + }, + { + "name": "Sergey Simonchik", + "email": "sergey.simonchik@jetbrains.com" + }, + { + "name": "Sergio Santoro", + "email": "santoro.srg@gmail.com" + }, + { + "name": "Shaine Hatch", + "email": "shaine@squidtree.com" + }, + { + "name": "Simon Goumaz", + "email": "simon@attentif.ch" + }, + { + "name": "Sorin Iclanzan", + "email": "sorin@iclanzan.com" + }, + { + "name": "Standa Opichal", + "email": "opichals@gmail.com" + }, + { + "name": "Stephen Mathieson", + "email": "smath23@gmail.com" + }, + { + "name": "Steve Mason", + "email": "stevem@brandwatch.com" + }, + { + "name": "Stewart Taylor", + "email": "stewart.taylor1@gmail.com" + }, + { + "name": "Stone", + "email": "baoshi.li@adleida.com" + }, + { + "name": "Tapiwa Kelvin", + "email": "tapiwa@munzwa.tk" + }, + { + "name": "Teddy Zeenny", + "email": "teddyzeenny@gmail.com" + }, + { + "name": "Thedark1337", + "email": "thedark1337@thedark1337.com" + }, + { + "name": "Tim Ehat", + "email": "timehat@gmail.com" + }, + { + "name": "Tingan Ho", + "email": "tingan87@gmail.com" + }, + { + "name": "Todd Agulnick", + "email": "tagulnick@onjack.com" + }, + { + "name": "Tom Coquereau", + "email": "tom@thau.me" + }, + { + "name": "Tom Hughes", + "email": "tom@compton.nu" + }, + { + "name": "Vadim Nikitin", + "email": "vnikiti@ncsu.edu" + }, + { + "name": "Victor Costan", + "email": "costan@gmail.com" + }, + { + "name": "Will Langstroth", + "email": "william.langstroth@gmail.com" + }, + { + "name": "Yanis Wang", + "email": "yanis.wang@gmail.com" + }, + { + "name": "Yuest Wang", + "email": "yuestwang@gmail.com" + }, + { + "name": "Zsolt Takács", + "email": "zsolt@takacs.cc" + }, + { + "name": "abrkn", + "email": "a@abrkn.com" + }, + { + "name": "airportyh", + "email": "airportyh@gmail.com" + }, + { + "name": "amsul", + "email": "reach@amsul.ca" + }, + { + "name": "badunk", + "email": "baduncaduncan@gmail.com" + }, + { + "name": "claudyus", + "email": "claudyus@HEX.(none)", + "url": "none" + }, + { + "name": "fengmk2", + "email": "fengmk2@gmail.com" + }, + { + "name": "gaye", + "email": "gaye@mozilla.com" + }, + { + "name": "gigadude", + "email": "gigadude@users.noreply.github.com" + }, + { + "name": "grasGendarme", + "email": "me@grasgendar.me" + }, + { + "name": "klaemo", + "email": "klaemo@fastmail.fm" + }, + { + "name": "lakmeer", + "email": "lakmeerkravid@gmail.com" + }, + { + "name": "lodr", + "email": "salva@unoyunodiez.com" + }, + { + "name": "mrShturman", + "email": "mrshturman@gmail.com" + }, + { + "name": "nexdrew", + "email": "andrew.goode@nextraq.com" + }, + { + "name": "nishigori", + "email": "Takuya_Nishigori@voyagegroup.com" + }, + { + "name": "omardelarosa", + "email": "thedelarosa@gmail.com" + }, + { + "name": "qiuzuhui", + "email": "qiuzuhui@users.noreply.github.com" + }, + { + "name": "ryym", + "email": "ryym.64@gmail.com" + }, + { + "name": "samuel goldszmidt", + "email": "samuel.goldszmidt@gmail.com" + }, + { + "name": "sebv", + "email": "seb.vincent@gmail.com" + }, + { + "name": "slyg", + "email": "syl.faucherand@gmail.com" + }, + { + "name": "startswithaj", + "email": "jake.mc@icloud.com" + }, + { + "name": "tgautier@yahoo.com", + "email": "tgautier@gmail.com" + }, + { + "name": "tmont", + "email": "tommy.mont@gmail.com" + }, + { + "name": "traleig1", + "email": "darkphoenix739@gmail.com" + }, + { + "name": "vlad", + "email": "iamvlad@gmail.com" + }, + { + "name": "wsw", + "email": "wsw0108@gmail.com" + }, + { + "name": "yuitest", + "email": "yuitest@cjhat.net" + }, + { + "name": "Aaron Hamid", + "email": "aaron.hamid@gmail.com" + }, + { + "name": "zhiyelee", + "email": "zhiyelee@gmail.com" + }, + { + "name": "Aaron Krause", + "email": "aaronjkrause@gmail.com" + }, + { + "name": "Adam Crabtree", + "email": "adam.crabtree@redrobotlabs.com" + }, + { + "name": "Adrian Ludwig", + "email": "me@adrianludwig.pl" + }, + { + "name": "Ajay Kodali", + "email": "ajay.kodali@citrix.com" + }, + { + "name": "Andreas Brekken", + "email": "andreas@opuno.com" + }, + { + "name": "Andrew Nesbitt", + "email": "andrewnez@gmail.com" + }, + { + "name": "Andrey Popp", + "email": "8mayday@gmail.com" + }, + { + "name": "Andrii Shumada", + "email": "eagleeyes91@gmail.com" + }, + { + "name": "Anis Safine", + "email": "anis.safine.ext@francetv.fr" + }, + { + "name": "Arnaud Brousseau", + "email": "arnaud.brousseau@gmail.com" + }, + { + "name": "Atsuya Takagi", + "email": "asoftonight@gmail.com" + }, + { + "name": "Austin Birch", + "email": "mraustinbirch@gmail.com" + }, + { + "name": "Ben Noordhuis", + "email": "info@bnoordhuis.nl" + }, + { + "name": "Ben Vinegar", + "email": "ben@benv.ca" + }, + { + "name": "Benoit Larroque", + "email": "zeta.ben@gmail.com" + }, + { + "name": "Benoît Zugmeyer", + "email": "bzugmeyer@gmail.com" + }, + { + "name": "Berker Peksag", + "email": "berker.peksag@gmail.com" + }, + { + "name": "Bjørge Næss", + "email": "bjoerge@origo.no" + }, + { + "name": "Brian Lalor", + "email": "blalor@bravo5.org" + }, + { + "name": "Brian M. Carlson", + "email": "brian.m.carlson@gmail.com" + }, + { + "name": "Brian Moore", + "email": "guardbionic-github@yahoo.com" + }, + { + "name": "Bryan Donovan", + "email": "bdondo@gmail.com" + }, + { + "name": "C. Scott Ananian", + "email": "cscott@cscott.net" + }, + { + "name": "Casey Foster", + "email": "casey@caseywebdev.com" + }, + { + "name": "Charles Lowell", + "email": "cowboyd@frontside.io" + }, + { + "name": "Chris Buckley", + "email": "chris@cmbuckley.co.uk" + }, + { + "name": "ChrisWren", + "email": "cthewren@gmail.com" + }, + { + "name": "Connor Dunn", + "email": "connorhd@gmail.com" + }, + { + "name": "Corey Butler", + "email": "corey@coreybutler.com" + }, + { + "name": "Daniel Stockman", + "email": "daniel.stockman@gmail.com" + }, + { + "name": "Dave McKenna", + "email": "davemckenna01@gmail.com" + }, + { + "name": "Denis Bardadym", + "email": "bardadymchik@gmail.com" + }, + { + "name": "Devin Weaver", + "email": "suki@tritarget.org" + }, + { + "name": "Di Wu", + "email": "dwu@palantir.com" + }, + { + "name": "Diogo Monteiro", + "email": "diogo.gmt@gmail.com" + }, + { + "name": "Dmitry Shirokov", + "email": "deadrunk@gmail.com" + }, + { + "name": "Dominic Barnes", + "email": "dominic@dbarnes.info" + }, + { + "name": "Douglas Christopher Wilson", + "email": "doug@somethingdoug.com" + }, + { + "name": "Duncan Beevers", + "email": "duncan@dweebd.com" + }, + { + "name": "Fede Ramirez", + "email": "i@2fd.me" + }, + { + "name": "Fedor Indutny", + "email": "fedor.indutny@gmail.com" + }, + { + "name": "Florian Margaine", + "email": "florian@margaine.com" + }, + { + "name": "Frederico Silva", + "email": "frederico.silva@gmail.com" + }, + { + "name": "Fredrik Lindin", + "email": "fredriklindin@gmail.com" + }, + { + "name": "Gabriel Silk", + "email": "gabesilk@gmail.com" + }, + { + "name": "Gareth Murphy", + "email": "gareth.cpm@gmail.com" + }, + { + "name": "Gavin Mogan", + "email": "GavinM@airg.com" + }, + { + "name": "Giovanni Bassi", + "email": "giggio@giggio.net" + }, + { + "name": "Glen Huang", + "email": "curvedmark@gmail.com" + }, + { + "name": "Greg Perkins", + "email": "gregperkins@alum.mit.edu" + }, + { + "name": "Guy Arye", + "email": "arye.guy@gmail.com" + }, + { + "name": "Gyandeep Singh", + "email": "gyandeeps@gmail.com" + }, + { + "name": "Harish", + "email": "hyeluri@gmail.com" + }, + { + "name": "Harry Brundage", + "email": "harry.brundage@gmail.com" + }, + { + "name": "Herman Junge", + "email": "herman@geekli.st" + }, + { + "name": "Ian Young", + "email": "ian.greenleaf@gmail.com" + }, + { + "name": "Ian Zamojc", + "email": "ian@thesecretlocation.net" + }, + { + "name": "Ivan", + "email": "ivan@kinvey.com" + }, + { + "name": "JP Bochi", + "email": "jpbochi@gmail.com" + }, + { + "name": "Jaakko Salonen", + "email": "jaakko.salonen@iki.fi" + }, + { + "name": "Jake Craige", + "email": "james.craige@gmail.com" + }, + { + "name": "Jake Marsh", + "email": "jakemmarsh@gmail.com" + }, + { + "name": "Jakub Nešetřil", + "email": "jakub@apiary.io" + }, + { + "name": "James Bowes", + "email": "jbowes@repl.ca" + }, + { + "name": "James G. Kim", + "email": "jgkim@jayg.org" + }, + { + "name": "James Lal", + "email": "james@lightsofapollo.com" + }, + { + "name": "Jan Kopriva", + "email": "jan.kopriva@gooddata.com" + }, + { + "name": "Jason Barry", + "email": "jay@jcbarry.com" + }, + { + "name": "Jason Lai", + "email": "jason@getpebble.com" + }, + { + "name": "Javier Aranda", + "email": "javierav@javierav.com" + }, + { + "name": "Jean Ponchon", + "email": "gelule@gmail.com" + }, + { + "name": "Jeff Kunkle", + "email": "jeff.kunkle@nearinfinity.com" + }, + { + "name": "Jeff Schilling", + "email": "jeff.schilling@q2ebanking.com" + }, + { + "name": "Jeremy Martin", + "email": "jmar777@gmail.com" + }, + { + "name": "Jimmy Cuadra", + "email": "jimmy@jimmycuadra.com" + }, + { + "name": "Joao Moreno", + "email": "mail@joaomoreno.com" + }, + { + "name": "Joey Cozza", + "email": "joey@grow.com" + }, + { + "name": "John Doty", + "email": "jrhdoty@gmail.com" + }, + { + "name": "Johnathon Sanders", + "email": "outdooricon@gmail.com" + }, + { + "name": "Jonas Dohse", + "email": "jonas@mbr-targeting.com" + }, + { + "name": "Jonathan Creamer", + "email": "matrixhasyou2k4@gmail.com" + }, + { + "name": "Jonathan Delgado", + "email": "jdelgado@rewip.com" + }, + { + "name": "Jonathan Kim", + "email": "jkimbo@gmail.com" + }, + { + "name": "Jonathan Park", + "email": "jpark@daptiv.com" + } + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/mochajs/mocha.git" + }, + "bin": { + "mocha": "./bin/mocha", + "_mocha": "./bin/_mocha" + }, + "engines": { + "node": ">= 0.8.x" + }, + "scripts": { + "test": "make test" + }, + "dependencies": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + }, + "devDependencies": { + "browser-stdout": "^1.2.0", + "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", + "watchify": "^3.7.0" + }, + "files": [ + "bin", + "images", + "lib", + "index.js", + "mocha.css", + "mocha.js", + "LICENSE" + ], + "browser": { + "debug": "./lib/browser/debug.js", + "events": "./lib/browser/events.js", + "tty": "./lib/browser/tty.js", + "./index.js": "./browser-entry.js", + "jade": false, + "fs": false, + "glob": false, + "path": false, + "supports-color": false + }, + "licenses": [ + { + "type": "MIT", + "url": "https://raw.github.com/mochajs/mocha/master/LICENSE" + } + ], + "gitHead": "e939d8e4379a622e28064ca3a75f3e1bda7e225b", + "bugs": { + "url": "https://github.com/mochajs/mocha/issues" + }, + "homepage": "https://github.com/mochajs/mocha#readme", + "_id": "mocha@2.5.3", + "_shasum": "161be5bdeb496771eb9b35745050b622b5aefc58", + "_from": "mocha@latest", + "_npmVersion": "3.8.6", + "_nodeVersion": "6.0.0", + "_npmUser": { + "name": "dasilvacontin", + "email": "dasilvacontin@gmail.com" + }, + "dist": { + "shasum": "161be5bdeb496771eb9b35745050b622b5aefc58", + "tarball": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz" + }, + "maintainers": [ + { + "name": "boneskull", + "email": "boneskull@boneskull.com" + }, + { + "name": "dasilvacontin", + "email": "dasilvacontin@gmail.com" + }, + { + "name": "travisjeffery", + "email": "tj@travisjeffery.com" + } + ], + "_npmOperationalInternal": { + "host": "packages-16-east.internal.npmjs.com", + "tmp": "tmp/mocha-2.5.3.tgz_1464165855561_0.11252999701537192" + }, + "directories": {}, + "_resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/node_modules/supertest/.npmignore b/node_modules/supertest/.npmignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/node_modules/supertest/.npmignore @@ -0,0 +1 @@ +node_modules diff --git a/node_modules/supertest/.travis.yml b/node_modules/supertest/.travis.yml new file mode 100644 index 0000000..471b276 --- /dev/null +++ b/node_modules/supertest/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "5" + - "4" + - "0.12" + - "0.10" diff --git a/node_modules/supertest/History.md b/node_modules/supertest/History.md new file mode 100644 index 0000000..6960f8a --- /dev/null +++ b/node_modules/supertest/History.md @@ -0,0 +1,181 @@ +1.2.0 / 2016-02-11 +=================== + + * PR-302 - Update to superagent ^1.7.2 + * PR-313 - Update node versions on Travis CI + * PR-223 - Remove Makefile for running tests + * PR-286 - Fix bug with redirects + +1.1.0 / 2015-08-26 +=================== + + * PR-235 - Update test framework to express 4, update other deps + * PR-239 - Core refactor to run expectations in order of definition + * PR-273 - Documentation update related to PR-239 + * PR-268 - Bump superagent to 1.3.0 + +1.0.1 / 2015-05-08 +=================== + + * PR-224 - Better expected error support as result of super-agent 1.x + +1.0.0 / 2015-05-08 +=================== + + * Bumping version to 1.0.0!, big changes with superagent + * Update superagent dependency to 1.2.0 + +0.15.0 / 2014-11-11 +=================== + + * Update superagent dependency + +0.14.0 / 2014-09-29 +=================== + + * Update superagent dependency + * Update methods dependency + +0.13.0 / 2014-05-22 +=================== + + * Wait for server close before invoke the callback for `end()` + * Fix global leak in tests + +0.12.1 / 2014-05-09 +=================== + + * update methods dependency + +0.11.0 / 2014-04-14 +================== + + * close internal server upon test end + * add .delete() method (aliases .del()) + +0.10.0 / 2014-03-20 +================== + + * assert respond body prior to the status code + * add documentation for .agent() + +0.9.2 / 2014-03-17 +================== + + * fix package.json + +0.9.1 / 2014-03-17 +================== + + * update superagent + +0.9.0 / 2014-01-17 +================== + + * add expect(function(res) {}) syntax + +0.8.3 / 2014-01-07 +================== + + * update superagent. + +0.8.2 / 2013-11-26 +================== + + * update superagent. Closes #85 + +0.8.1 / 2013-10-28 +================== + + * merge pull request #82 from jonathanong/patch-1 + * bump node-methods + * merge pull request #79 from menzoic/patch-1 + * update Readme.md + * Merge pull request #73 from repoify/add/repository + * add repository field to readme + +0.8.0 / 2013-08-09 +================== + + * add ability for multiple assertions per header + +0.7.1 / 2013-07-02 +================== + + * update superagent + +0.7.0 / 2013-06-04 +================== + + * add error properties so test frameworks can show diffs etc. Closes #65 + +0.6.1 / 2013-06-02 +================== + + * fix: EADDRINUSE errnos, use ephemeral ports now + * fix: handling of socket errors + +0.6.0 / 2013-04-15 +================== + + * add exposing of `Test` to enable extensibility + * add request.agent(app) support + * add request(url) test. Closes #33 + +0.5.1 2012-12-07 +================== + + * fix .expect(status) should assert only status + +0.5.0/ 2012-11-28 +================== + + * add support for multiple body assertions + +0.4.2 / 2012-11-17 +================== + + * add .buffer() so that responses with no content-length are testable. closes #36 + * add failing test for #36 + * update superagent + +0.4.1 / 2012-11-14 +================== + + * update superagent + +0.4.0 / 2012-10-18 +================== + + * add url support [vesln] + +0.3.1 / 2012-10-01 +================== + + * update superagent + +0.3.0 / 2012-09-24 +================== + + * add `https.Server` support [fengmk2] + +0.2.0 / 2012-08-29 +================== + + * update superagent. Closes #18 + +0.1.2 / 2012-07-15 +================== + + * change bind address from 0.0.0.0 to 127.0.0.1 to prevent EADDRNOTAVAIL on windows + +0.1.1 / 2012-07-03 +================== + + * add `.expect(status, body, fn)` support + * add `.expect(status, body)` support + +0.1.0 / 2012-07-02 +================== + + * add parsed body assertion support. Closes #1 diff --git a/node_modules/supertest/LICENSE b/node_modules/supertest/LICENSE new file mode 100644 index 0000000..a7693b0 --- /dev/null +++ b/node_modules/supertest/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014 TJ Holowaychuk + +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. diff --git a/node_modules/supertest/Readme.md b/node_modules/supertest/Readme.md new file mode 100644 index 0000000..daf1b43 --- /dev/null +++ b/node_modules/supertest/Readme.md @@ -0,0 +1,222 @@ +# SuperTest [![Build Status](https://travis-ci.org/visionmedia/supertest.svg?branch=master)](https://travis-ci.org/visionmedia/supertest) [![npm version](https://badge.fury.io/js/supertest.svg)](https://www.npmjs.com/package/supertest) + + HTTP assertions made easy via [super-agent](http://github.com/visionmedia/superagent). + +## About + + The motivation with this module is to provide a high-level abstraction for testing + HTTP, while still allowing you to drop down to the lower-level API provided by super-agent. + +## Getting Started + + Install SuperTest as an npm module and save it to your package.json file as a development dependency: + ``` +npm install supertest --save-dev + ``` + + Once installed it can now be referenced by simply calling ```require("supertest");``` + +## Example + + You may pass an `http.Server`, or a `Function` to `request()` - if the server is not + already listening for connections then it is bound to an ephemeral port for you so + there is no need to keep track of ports. + + SuperTest works with any test framework, here is an example without using any + test framework at all: + +```js +var request = require('supertest') + , express = require('express'); + +var app = express(); + +app.get('/user', function(req, res){ + res.status(200).json({ name: 'tobi' }); +}); + +request(app) + .get('/user') + .expect('Content-Type', /json/) + .expect('Content-Length', '15') + .expect(200) + .end(function(err, res){ + if (err) throw err; + }); +``` + + Here's an example with mocha, note how you can pass `done` straight to any of the `.expect()` calls: + +```js +describe('GET /user', function(){ + it('respond with json', function(done){ + request(app) + .get('/user') + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect(200, done); + }) +}) +``` + +One thing to note with the above statement is that superagent now sends any HTTP +error (anything other than a 2XX response code) to the callback as the first argument if +you do not add a status code expect (i.e. `.expect(302)`). + + If you are using the `.end()` method `.expect()` assertions that fail will + not throw - they will return the assertion as an error to the `.end()` callback. In + order to fail the test case, you will need to rethrow or pass `err` to `done()`, as follows: + +```js +describe('GET /users', function(){ + it('respond with json', function(done){ + request(app) + .get('/user') + .set('Accept', 'application/json') + .expect(200) + .end(function(err, res){ + if (err) return done(err); + done(); + }); + }); +}); +``` + + Expectations are run in the order of definition. This characteristic can be used + to modify the response body or headers before executing an assertion. + +```js +describe('GET /user', function(){ + it('user.name should be an case-insensitive match for "tobi"', function(done){ + request(app) + .get('/user') + .set('Accept', 'application/json') + .expect(function(res) { + res.body.id = 'some fixed id'; + res.body.name = res.body.name.toUpperCase(); + }) + .expect(200, { + id: 'some fixed id', + name: 'TOBI' + }, done); + }); +}); + +``` + + Anything you can do with superagent, you can do with supertest - for example multipart file uploads! + +```js +request(app) +.post('/') +.field('name', 'my awesome avatar') +.attach('avatar', 'test/fixtures/homeboy.jpg') +... +``` + + Passing the app or url each time is not necessary, if you're testing + the same host you may simply re-assign the request variable with the + initialization app or url, a new `Test` is created per `request.VERB()` call. + +```js +request = request('http://localhost:5555'); + +request.get('/').expect(200, function(err){ + console.log(err); +}); + +request.get('/').expect('heya', function(err){ + console.log(err); +}); +``` + Here's an example with mocha that shows how to persist a request and its cookies: + +```js +var request = require('supertest') + , should = require('should') + , express = require('express'); + + +describe('request.agent(app)', function(){ + var app = express(); + app.use(express.cookieParser()); + + app.get('/', function(req, res){ + res.cookie('cookie', 'hey'); + res.send(); + }); + + app.get('/return', function(req, res){ + if (req.cookies.cookie) res.send(req.cookies.cookie); + else res.send(':(') + }); + + var agent = request.agent(app); + + it('should save cookies', function(done){ + agent + .get('/') + .expect('set-cookie', 'cookie=hey; Path=/', done); + }) + + it('should send cookies', function(done){ + agent + .get('/return') + .expect('hey', done); + }) +}) +``` + There is another example that is introduced by the file [agency.js](https://github.com/visionmedia/superagent/blob/master/test/node/agency.js) + +## API + + You may use any [super-agent](http://github.com/visionmedia/superagent) methods, + including `.write()`, `.pipe()` etc and perform assertions in the `.end()` callback + for lower-level needs. + +### .expect(status[, fn]) + + Assert response `status` code. + +### .expect(status, body[, fn]) + + Assert response `status` code and `body`. + +### .expect(body[, fn]) + + Assert response `body` text with a string, regular expression, or + parsed body object. + +### .expect(field, value[, fn]) + + Assert header `field` `value` with a string or regular expression. + +### .expect(function(res) {}) + + Pass a custom assertion function. It'll be given the response object to check. If the response is ok, it should return falsy, most commonly by not returning anything. If the check fails, throw an error or return a truthy value like a string that'll be turned into an error. + + Here the string or error throwing options are both demonstrated: + + ```js + request(app) + .get('/') + .expect(hasPreviousAndNextKeys) + .end(done); + + function hasPreviousAndNextKeys(res) { + if (!('next' in res.body)) return "missing next key"; + if (!('prev' in res.body)) throw new Error("missing prev key"); + } + ``` + +### .end(fn) + + Perform the request and invoke `fn(err, res)`. + +## Notes + + Inspired by [api-easy](https://github.com/flatiron/api-easy) minus vows coupling. + +## License + + MIT diff --git a/node_modules/supertest/example.js b/node_modules/supertest/example.js new file mode 100644 index 0000000..d128ab7 --- /dev/null +++ b/node_modules/supertest/example.js @@ -0,0 +1,20 @@ + +var request = require('./') + , express = require('express'); + +var app = express(); + +app.get('/user', function(req, res){ + res.status(201).json({ name: 'tobi' }); +}); + +request(app) + .get('/user') + .expect('Content-Type', /json/) + .expect('Content-Length', '15') + .expect(201) + .end(function(err, res){ + if (err) throw err; + console.log('done'); + process.exit(); + }); diff --git a/node_modules/supertest/index.js b/node_modules/supertest/index.js new file mode 100644 index 0000000..41a75d5 --- /dev/null +++ b/node_modules/supertest/index.js @@ -0,0 +1,45 @@ + +/** + * Module dependencies. + */ + +var methods = require('methods') + , Test = require('./lib/test') + , http = require('http'); + +/** + * Test against the given `app`, + * returning a new `Test`. + * + * @param {Function|Server} app + * @return {Test} + * @api public + */ + +module.exports = function(app){ + if ('function' == typeof app) app = http.createServer(app); + var obj = {}; + + methods.forEach(function(method){ + obj[method] = function(url){ + return new Test(app, method, url); + }; + }); + + // Support previous use of del + obj.del = obj['delete']; + + return obj; +}; + +/** + * Expose `Test` + */ + +module.exports.Test = Test; + +/** + * Expose the agent function + */ + +module.exports.agent = require('./lib/agent'); diff --git a/node_modules/supertest/lib/agent.js b/node_modules/supertest/lib/agent.js new file mode 100644 index 0000000..ccd2cfd --- /dev/null +++ b/node_modules/supertest/lib/agent.js @@ -0,0 +1,54 @@ + +/** + * Module dependencies. + */ + +var Agent = require('superagent').agent + , methods = require('methods') + , http = require('http') + , Test = require('./test'); + +/** + * Expose `Agent`. + */ + +module.exports = TestAgent; + +/** + * Initialize a new `TestAgent`. + * + * @param {Function|Server} app + * @param {Object} options + * @api public + */ + +function TestAgent(app, options){ + if (!(this instanceof TestAgent)) return new TestAgent(app, options); + if ('function' == typeof app) app = http.createServer(app); + if (options) this._ca = options.ca; + Agent.call(this); + this.app = app; +} + +/** + * Inherits from `Agent.prototype`. + */ + +TestAgent.prototype.__proto__ = Agent.prototype; + +// override HTTP verb methods +methods.forEach(function(method){ + TestAgent.prototype[method] = function(url, fn){ + var req = new Test(this.app, method.toUpperCase(), url); + req.ca(this._ca); + + req.on('response', this.saveCookies.bind(this)); + req.on('redirect', this.saveCookies.bind(this)); + req.on('redirect', this.attachCookies.bind(this, req)); + this.attachCookies(req); + + return req; + }; +}); + +TestAgent.prototype.del = TestAgent.prototype.delete; diff --git a/node_modules/supertest/lib/test.js b/node_modules/supertest/lib/test.js new file mode 100644 index 0000000..6bdca85 --- /dev/null +++ b/node_modules/supertest/lib/test.js @@ -0,0 +1,270 @@ +/** + * Module dependencies. + */ + +var request = require('superagent') + , util = require('util') + , http = require('http') + , https = require('https') + , assert = require('assert') + , Request = request.Request; + +/** + * Expose `Test`. + */ + +module.exports = Test; + +/** + * Initialize a new `Test` with the given `app`, + * request `method` and `path`. + * + * @param {Server} app + * @param {String} method + * @param {String} path + * @api public + */ + +function Test(app, method, path) { + Request.call(this, method, path); + this.redirects(0); + this.buffer(); + this.app = app; + this._asserts = []; + this.url = 'string' == typeof app + ? app + path + : this.serverAddress(app, path); +} + +/** + * Inherits from `Request.prototype`. + */ + +Test.prototype.__proto__ = Request.prototype; + +/** + * Returns a URL, extracted from a server. + * + * @param {Server} app + * @param {String} path + * @returns {String} URL address + * @api private + */ + +Test.prototype.serverAddress = function(app, path){ + var addr = app.address(); + if (!addr) this._server = app.listen(0); + var port = app.address().port; + var protocol = app instanceof https.Server ? 'https' : 'http'; + return protocol + '://127.0.0.1:' + port + path; +}; + +/** + * Expectations: + * + * .expect(200) + * .expect(200, fn) + * .expect(200, body) + * .expect('Some body') + * .expect('Some body', fn) + * .expect('Content-Type', 'application/json') + * .expect('Content-Type', 'application/json', fn) + * .expect(fn) + * + * @return {Test} + * @api public + */ + +Test.prototype.expect = function(a, b, c){ + // callback + if ('function' == typeof a) { + this._asserts.push(a); + return this; + } + if ('function' == typeof b) this.end(b); + if ('function' == typeof c) this.end(c); + + // status + if ('number' == typeof a) { + this._asserts.push(this._assertStatus.bind(this, a)); + // body + if ('function' != typeof b && arguments.length > 1) + this._asserts.push(this._assertBody.bind(this, b)); + return this; + } + + // header field + if ('string' == typeof b || 'number' == typeof b || b instanceof RegExp) { + this._asserts.push(this._assertHeader.bind(this, {name: ''+a, value: b})); + return this; + } + + // body + this._asserts.push(this._assertBody.bind(this, a)); + + return this; +}; + +/** + * Defer invoking superagent's `.end()` until + * the server is listening. + * + * @param {Function} fn + * @api public + */ + +Test.prototype.end = function(fn){ + var self = this; + var server = this._server; + var end = Request.prototype.end; + + end.call(this, function(err, res){ + if (server && server._handle) return server.close(assert); + + assert(); + + function assert(){ + self.assert(err, res, fn); + } + }); + + return this; +}; + +/** + * Perform assertions and invoke `fn(err, res)`. + * + * @param {?Error} resError + * @param {Response} res + * @param {Function} fn + * @api private + */ + +Test.prototype.assert = function(resError, res, fn){ + var error; + + // asserts + for (var i = 0; i < this._asserts.length && !error; ++i) { + error = this._assertFunction(this._asserts[i], res); + } + + // set unexpected superagent error if no other error has occurred. + if (!error && resError instanceof Error && + (!res || resError.status !== res.status)) + error = resError; + + fn.call(this, error || null, res); +}; + +/** + * Perform assertions on a response body and return an Error upon failure. + * + * @param {Mixed} body + * @param {Response} res + * @return {?Error} + * @api private + */ + +Test.prototype._assertBody = function(body, res) { + var isregexp = body instanceof RegExp; + // parsed + if ('object' == typeof body && !isregexp) { + try { + assert.deepEqual(body, res.body); + } catch (err) { + var a = util.inspect(body); + var b = util.inspect(res.body); + return error('expected ' + a + ' response body, got ' + b, body, res.body); + } + } else { + // string + if (body !== res.text) { + var a = util.inspect(body); + var b = util.inspect(res.text); + + // regexp + if (isregexp) { + if (!body.test(res.text)) { + return error('expected body ' + b + ' to match ' + body, body, res.body); + } + } else { + return error('expected ' + a + ' response body, got ' + b, body, res.body); + } + } + } +}; + +/** + * Perform assertions on a response header and return an Error upon failure. + * + * @param {Object} header + * @param {Response} res + * @return {?Error} + * @api private + */ + +Test.prototype._assertHeader = function(header, res) { + var field = header.name; + var actual = res.header[field.toLowerCase()]; + if (null == actual) return new Error('expected "' + field + '" header field'); + var fieldExpected = header.value; + if (fieldExpected == actual) return; + if (fieldExpected instanceof RegExp) { + if (!fieldExpected.test(actual)) return new Error('expected "' + field + '" matching ' + fieldExpected + ', got "' + actual + '"'); + } else { + return new Error('expected "' + field + '" of "' + fieldExpected + '", got "' + actual + '"'); + } +}; + +/** + * Perform assertions on the response status and return an Error upon failure. + * + * @param {Number} status + * @param {Response} res + * @return {?Error} + * @api private + */ + +Test.prototype._assertStatus = function(status, res) { + if (res.status !== status) { + var a = http.STATUS_CODES[status]; + var b = http.STATUS_CODES[res.status]; + return new Error('expected ' + status + ' "' + a + '", got ' + res.status + ' "' + b + '"'); + } +}; + +/** + * Performs an assertion by calling a function and return an Error upon failure. + * + * @param {Function} fn + * @param {Response} res + * @return {?Error} + * @api private + */ +Test.prototype._assertFunction = function(check, res) { + var err; + try { + err = check(res); + } catch(e) { + err = e; + } + if (err instanceof Error) return err; +}; + +/** + * Return an `Error` with `msg` and results properties. + * + * @param {String} msg + * @param {Mixed} expected + * @param {Mixed} actual + * @return {Error} + * @api private + */ + +function error(msg, expected, actual) { + var err = new Error(msg); + err.expected = expected; + err.actual = actual; + err.showDiff = true; + return err; +} diff --git a/node_modules/supertest/node_modules/superagent/.npmignore b/node_modules/supertest/node_modules/superagent/.npmignore new file mode 100644 index 0000000..90d998b --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/.npmignore @@ -0,0 +1,6 @@ +support +test +examples +*.sock +lib-cov +coverage.html diff --git a/node_modules/supertest/node_modules/superagent/.travis.yml b/node_modules/supertest/node_modules/superagent/.travis.yml new file mode 100644 index 0000000..0262c01 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/.travis.yml @@ -0,0 +1,18 @@ +sudo: false +language: node_js +node_js: + - "5.4" + - "4.2" + - "0.12" + - "0.10" + - "iojs" + +env: + global: + - SAUCE_USERNAME='shtylman-superagent' + - SAUCE_ACCESS_KEY='39a45464-cb1d-4b8d-aa1f-83c7c04fa673' + +matrix: + include: + - node_js: "4.2" + env: BROWSER=1 diff --git a/node_modules/supertest/node_modules/superagent/.zuul.yml b/node_modules/supertest/node_modules/superagent/.zuul.yml new file mode 100644 index 0000000..031c56a --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/.zuul.yml @@ -0,0 +1,15 @@ +ui: mocha-bdd +server: ./test/support/server.js +browsers: + - name: chrome + version: latest + - name: firefox + version: latest + - name: safari + version: latest + - name: iphone + version: latest + - name: android + version: latest + - name: ie + version: 9..latest diff --git a/node_modules/supertest/node_modules/superagent/Contributing.md b/node_modules/supertest/node_modules/superagent/Contributing.md new file mode 100644 index 0000000..1eca592 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/Contributing.md @@ -0,0 +1,7 @@ +When submitting a PR, your chance of acceptance increases if you do the following: + +* Code style is consistent with existing in the file. +* Tests are passing (client and server). +* You add a test for the failing issue you are fixing. +* Code changes are focused on the area of discussion. +* Do not rebuild the distribution files or increment version numbers. diff --git a/node_modules/supertest/node_modules/superagent/History.md b/node_modules/supertest/node_modules/superagent/History.md new file mode 100644 index 0000000..553a5ea --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/History.md @@ -0,0 +1,554 @@ +# 1.8.2 (2016-03-20) + + * Fixed handling of HTTP status 204 with content-encoding: gzip (Andrew Shelton) + * Handling of FormData error events (scriptype) + * Fixed parsing of `vnd+json` MIME types (Kornel Lesiński) + * Aliased browser implementation of `.parse()` as `.serialize()` for forward compatibility + +# 1.8.1 (2016-03-14) + + * Fixed form-data incompatibility with IE9 + +# 1.8.0 (2016-03-09) + + * Extracted common code into request-base class (Peter Lyons) + * It does not affect the public API, but please let us know if you notice any plugins/subclasses breaking! + * Added option `{type:'auto'}` to `auth` method, which enables browser-native auth types (Jungle, Askar Yusupov) + * Added `responseType()` to set XHR `responseType` (chris) + * Switched to form-data for browserify-compatible `FormData` (Peter Lyons) + * Added `statusCode` to error response when JSON response is malformed (mattdell) + * Prevented TCP port conflicts in all tests (Peter Lyons) + * Updated form-data dependency + +# 1.7.2 (2016-01-26) + + * Fix case-sensitivity of header fields introduced by a4ddd6a. (Edward J. Jinotti) + * bump extend dependency, as former version did not contain any license information (Lukas Eipert) + +# 1.7.1 (2016-01-21) + + * Fixed a conflict with express when using npm 3.x (Glenn) + * Fixed redirects after a multipart/form-data POST request (cyclist2) + +# 1.7.0 (2016-01-18) + + * When attaching files, read default filename from the `File` object (JD Isaacks) + * Add `direction` property to `progress` events (Joseph Dykstra) + * Update component-emitter & formidable (Kornel Lesiński) + * Don't re-encode query string needlessly (Ruben Verborgh) + * ensure querystring is appended when doing `stream.pipe(request)` (Keith Grennan) + * change set header function, not call `this.request()` until call `this.end()` (vicanso) + * Add no-op `withCredentials` to Node API (markdalgleish) + * fix `delete` breaking on ie8 (kenjiokabe) + * Don't let request error override responses (Clay Reimann) + * Increased number of tests shared between node and client (Kornel Lesiński) + +# 1.6.0/1.6.1 (2015-12-09) + + * avoid misleading CORS error message + * added 'progress' event on file/form upload in Node (Olivier Lalonde) + * return raw response if the response parsing fails (Rei Colina) + * parse content-types ending with `+json` as JSON (Eiryyy) + * fix to avoid throwing errors on aborted requests (gjurgens) + * retain cookies on redirect when hosts match (Tom Conroy) + * added Bower manifest (Johnny Freeman) + * upgrade to latest cookiejar (Andy Burke) + +# 1.5.0 (2015-11-30) + + * encode array values as `key=1&key=2&key=3` etc... (aalpern, Davis Kim) + * avoid the error which is omitted from 'socket hang up' + * faster JSON parsing, handling of zlib errors (jbellenger) + * fix IE11 sends 'undefined' string if data was undefined (Vadim Goncharov) + * alias `del()` method as `delete()` (Aaron Krause) + * revert Request#parse since it was actually Response#parse + +# 1.4.0 (2015-09-14) + + * add Request#parse method to client library + * add missing statusCode in client response + * don't apply JSON heuristics if a valid parser is found + * fix detection of root object for webworkers + +# 1.3.0 (2015-08-05) + + * fix incorrect content-length of data set to buffer + * serialize request data takes into account charsets + * add basic promise support via a `then` function + +# 1.2.0 (2015-04-13) + + * add progress events to downlodas + * make usable in webworkers + * add support for 308 redirects + * update node-form-data dependency + * update to work in react native + * update node-mime dependency + +# 1.1.0 (2015-03-13) + + * Fix responseType checks without xhr2 and ie9 tests (rase-) + * errors have .status and .response fields if applicable (defunctzombie) + * fix end callback called before saving cookies (rase-) + +1.0.0 / 2015-03-08 +================== + + * All non-200 responses are treated as errors now. (The callback is called with an error when the response has a status < 200 or >= 300 now. In previous versions this would not have raised an error and the client would have to check the `res` object. See [#283](https://github.com/visionmedia/superagent/issues/283). + * keep timeouts intact across redirects (hopkinsth) + * handle falsy json values (themaarten) + * fire response events in browser version (Schoonology) + * getXHR exported in client version (KidsKilla) + * remove arity check on `.end()` callbacks (defunctzombie) + * avoid setting content-type for host objects (rexxars) + * don't index array strings in querystring (travisjeffery) + * fix pipe() with redirects (cyrilis) + * add xhr2 file download (vstirbu) + * set default response type to text/plain if not specified (warrenseine) + +0.21.0 / 2014-11-11 +================== + + * Trim text before parsing json (gjohnson) + * Update tests to express 4 (gaastonsr) + * Prevent double callback when error is thrown (pgn-vole) + * Fix missing clearTimeout (nickdima) + * Update debug (TooTallNate) + +0.20.0 / 2014-10-02 +================== + + * Add toJSON() to request and response instances. (yields) + * Prevent HEAD requests from getting parsed. (gjohnson) + * Update debug. (TooTallNate) + +0.19.1 / 2014-09-24 +================== + + * Fix basic auth issue when password is falsey value. (gjohnson) + +0.19.0 / 2014-09-24 +================== + + * Add unset() to browser. (shesek) + * Prefer XHR over ActiveX. (omeid) + * Catch parse errors. (jacwright) + * Update qs dependency. (wercker) + * Add use() to node. (Financial-Times) + * Add response text to errors. (yields) + * Don't send empty cookie headers. (undoZen) + * Don't parse empty response bodies. (DveMac) + * Use hostname when setting cookie host. (prasunsultania) + +0.18.2 / 2014-07-12 +================== + + * Handle parser errors. (kof) + * Ensure not to use default parsers when there is a user defined one. (kof) + +0.18.1 / 2014-07-05 +================== + + * Upgrade cookiejar dependency (juanpin) + * Support image mime types (nebulade) + * Make .agent chainable (kof) + * Upgrade debug (TooTallNate) + * Fix docs (aheckmann) + +0.18.0 / 2014-04-29 +=================== + +* Use "form-data" module for the multipart/form-data implementation. (TooTallNate) +* Add basic `field()` and `attach()` functions for HTML5 FormData. (TooTallNate) +* Deprecate `part()`. (TooTallNate) +* Set default user-agent header. (bevacqua) +* Add `unset()` method for removing headers. (bevacqua) +* Update cookiejar. (missinglink) +* Fix response error formatting. (shesek) + +0.17.0 / 2014-03-06 +=================== + + * supply uri malformed error to the callback (yields) + * add request event (yields) + * allow simple auth (yields) + * add request event (yields) + * switch to component/reduce (visionmedia) + * fix part content-disposition (mscdex) + * add browser testing via zuul (defunctzombie) + * adds request.use() (johntron) + +0.16.0 / 2014-01-07 +================== + + * remove support for 0.6 (superjoe30) + * fix CORS withCredentials (wejendorp) + * add "test" script (superjoe30) + * add request .accept() method (nickl-) + * add xml to mime types mappings (nickl-) + * fix parse body error on HEAD requests (gjohnson) + * fix documentation typos (matteofigus) + * fix content-type + charset (bengourley) + * fix null values on query parameters (cristiandouce) + +0.15.7 / 2013-10-19 +================== + + * pin should.js to 1.3.0 due to breaking change in 2.0.x + * fix browserify regression + +0.15.5 / 2013-10-09 +================== + + * add browser field to support browserify + * fix .field() value number support + +0.15.4 / 2013-07-09 +================== + + * node: add a Request#agent() function to set the http Agent to use + +0.15.3 / 2013-07-05 +================== + + * fix .pipe() unzipping on more recent nodes. Closes #240 + * fix passing an empty object to .query() no longer appends "?" + * fix formidable error handling + * update formidable + +0.15.2 / 2013-07-02 +================== + + * fix: emit 'end' when piping. + +0.15.1 / 2013-06-26 +================== + + * add try/catch around parseLinks + +0.15.0 / 2013-06-25 +================== + + * make `Response#toError()` have a more meaningful `message` + +0.14.9 / 2013-06-15 +================== + + * add debug()s to the node client + * add .abort() method to node client + +0.14.8 / 2013-06-13 +================== + + * set .agent = false always + * remove X-Requested-With. Closes #189 + +0.14.7 / 2013-06-06 +================== + + * fix unzip error handling + +0.14.6 / 2013-05-23 +================== + + * fix HEAD unzip bug + +0.14.5 / 2013-05-23 +================== + + * add flag to ensure the callback is __never__ invoked twice + +0.14.4 / 2013-05-22 +================== + + * add superagent.js build output + * update qs + * update emitter-component + * revert "add browser field to support browserify" see GH-221 + +0.14.3 / 2013-05-18 +================== + + * add browser field to support browserify + +0.14.2/ 2013-05-07 +================== + + * add host object check to fix serialization of File/Blobs etc as json + +0.14.1 / 2013-04-09 +================== + + * update qs + +0.14.0 / 2013-04-02 +================== + + * add client-side basic auth + * fix retaining of .set() header field case + +0.13.0 / 2013-03-13 +================== + + * add progress events to client + * add simple example + * add res.headers as alias of res.header for browser client + * add res.get(field) to node/client + +0.12.4 / 2013-02-11 +================== + + * fix get content-type even if can't get other headers in firefox. fixes #181 + +0.12.3 / 2013-02-11 +================== + + * add quick "progress" event support + +0.12.2 / 2013-02-04 +================== + + * add test to check if response acts as a readable stream + * add ReadableStream in the Response prototype. + * add test to assert correct redirection when the host changes in the location header. + * add default Accept-Encoding. Closes #155 + * fix req.pipe() return value of original stream for node parity. Closes #171 + * remove the host header when cleaning headers to properly follow the redirection. + +0.12.1 / 2013-01-10 +================== + + * add x-domain error handling + +0.12.0 / 2013-01-04 +================== + + * add header persistence on redirects + +0.11.0 / 2013-01-02 +================== + + * add .error Error object. Closes #156 + * add forcing of res.text removal for FF HEAD responses. Closes #162 + * add reduce component usage. Closes #90 + * move better-assert dep to development deps + +0.10.0 / 2012-11-14 +================== + + * add req.timeout(ms) support for the client + +0.9.10 / 2012-11-14 +================== + + * fix client-side .query(str) support + +0.9.9 / 2012-11-14 +================== + + * add .parse(fn) support + * fix socket hangup with dates in querystring. Closes #146 + * fix socket hangup "error" event when a callback of arity 2 is provided + +0.9.8 / 2012-11-03 +================== + + * add emission of error from `Request#callback()` + * add a better fix for nodes weird socket hang up error + * add PUT/POST/PATCH data support to client short-hand functions + * add .license property to component.json + * change client portion to build using component(1) + * fix GET body support [guille] + +0.9.7 / 2012-10-19 +================== + + * fix `.buffer()` `res.text` when no parser matches + +0.9.6 / 2012-10-17 +================== + + * change: use `this` when `window` is undefined + * update to new component spec [juliangruber] + * fix emission of "data" events for compressed responses without encoding. Closes #125 + +0.9.5 / 2012-10-01 +================== + + * add field name to .attach() + * add text "parser" + * refactor isObject() + * remove wtf isFunction() helper + +0.9.4 / 2012-09-20 +================== + + * fix `Buffer` responses [TooTallNate] + * fix `res.type` when a "type" param is present [TooTallNate] + +0.9.3 / 2012-09-18 +================== + + * remove __GET__ `.send()` == `.query()` special-case (__API__ change !!!) + +0.9.2 / 2012-09-17 +================== + + * add `.aborted` prop + * add `.abort()`. Closes #115 + +0.9.1 / 2012-09-07 +================== + + * add `.forbidden` response property + * add component.json + * change emitter-component to 0.0.5 + * fix client-side tests + +0.9.0 / 2012-08-28 +================== + + * add `.timeout(ms)`. Closes #17 + +0.8.2 / 2012-08-28 +================== + + * fix pathname relative redirects. Closes #112 + +0.8.1 / 2012-08-21 +================== + + * fix redirects when schema is specified + +0.8.0 / 2012-08-19 +================== + + * add `res.buffered` flag + * add buffering of text/*, json and forms only by default. Closes #61 + * add `.buffer(false)` cancellation + * add cookie jar support [hunterloftis] + * add agent functionality [hunterloftis] + +0.7.0 / 2012-08-03 +================== + + * allow `query()` to be called after the internal `req` has been created [tootallnate] + +0.6.0 / 2012-07-17 +================== + + * add `res.send('foo=bar')` default of "application/x-www-form-urlencoded" + +0.5.1 / 2012-07-16 +================== + + * add "methods" dep + * add `.end()` arity check to node callbacks + * fix unzip support due to weird node internals + +0.5.0 / 2012-06-16 +================== + + * Added "Link" response header field parsing, exposing `res.links` + +0.4.3 / 2012-06-15 +================== + + * Added 303, 305 and 307 as redirect status codes [slaskis] + * Fixed passing an object as the url + +0.4.2 / 2012-06-02 +================== + + * Added component support + * Fixed redirect data + +0.4.1 / 2012-04-13 +================== + + * Added HTTP PATCH support + * Fixed: GET / HEAD when following redirects. Closes #86 + * Fixed Content-Length detection for multibyte chars + +0.4.0 / 2012-03-04 +================== + + * Added `.head()` method [browser]. Closes #78 + * Added `make test-cov` support + * Added multipart request support. Closes #11 + * Added all methods that node supports. Closes #71 + * Added "response" event providing a Response object. Closes #28 + * Added `.query(obj)`. Closes #59 + * Added `res.type` (browser). Closes #54 + * Changed: default `res.body` and `res.files` to {} + * Fixed: port existing query-string fix (browser). Closes #57 + +0.3.0 / 2012-01-24 +================== + + * Added deflate/gzip support [guillermo] + * Added `res.type` (Content-Type void of params) + * Added `res.statusCode` to mirror node + * Added `res.headers` to mirror node + * Changed: parsers take callbacks + * Fixed optional schema support. Closes #49 + +0.2.0 / 2012-01-05 +================== + + * Added url auth support + * Added `.auth(username, password)` + * Added basic auth support [node]. Closes #41 + * Added `make test-docs` + * Added guillermo's EventEmitter. Closes #16 + * Removed `Request#data()` for SS, renamed to `send()` + * Removed `Request#data()` from client, renamed to `send()` + * Fixed array support. [browser] + * Fixed array support. Closes #35 [node] + * Fixed `EventEmitter#emit()` + +0.1.3 / 2011-10-25 +================== + + * Added error to callback + * Bumped node dep for 0.5.x + +0.1.2 / 2011-09-24 +================== + + * Added markdown documentation + * Added `request(url[, fn])` support to the client + * Added `qs` dependency to package.json + * Added options for `Request#pipe()` + * Added support for `request(url, callback)` + * Added `request(url)` as shortcut for `request.get(url)` + * Added `Request#pipe(stream)` + * Added inherit from `Stream` + * Added multipart support + * Added ssl support (node) + * Removed Content-Length field from client + * Fixed buffering, `setEncoding()` to utf8 [reported by stagas] + * Fixed "end" event when piping + +0.1.1 / 2011-08-20 +================== + + * Added `res.redirect` flag (node) + * Added redirect support (node) + * Added `Request#redirects(n)` (node) + * Added `.set(object)` header field support + * Fixed `Content-Length` support + +0.1.0 / 2011-08-09 +================== + + * Added support for multiple calls to `.data()` + * Added support for `.get(uri, obj)` + * Added GET `.data()` querystring support + * Added IE{6,7,8} support [alexyoung] + +0.0.1 / 2011-08-05 +================== + + * Initial commit + diff --git a/node_modules/supertest/node_modules/superagent/LICENSE b/node_modules/supertest/node_modules/superagent/LICENSE new file mode 100644 index 0000000..1b188ba --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014-2016 TJ Holowaychuk + +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. diff --git a/node_modules/supertest/node_modules/superagent/Makefile b/node_modules/supertest/node_modules/superagent/Makefile new file mode 100644 index 0000000..bac2be5 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/Makefile @@ -0,0 +1,57 @@ + +NODETESTS ?= test/*.js test/node/*.js +BROWSERTESTS ?= test/*.js test/client/*.js +REPORTER = spec + +all: superagent.js + +test: + @if [ "x$(BROWSER)" = "x" ]; then make test-node; else make test-browser; fi + +test-node: + @NODE_ENV=test NODE_TLS_REJECT_UNAUTHORIZED=0 ./node_modules/.bin/mocha \ + --require should \ + --reporter $(REPORTER) \ + --timeout 5000 \ + --growl \ + $(NODETESTS) + +test-cov: lib-cov + SUPERAGENT_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html + +test-browser: + ./node_modules/.bin/zuul -- $(BROWSERTESTS) + +test-browser-local: + ./node_modules/.bin/zuul --local 4000 -- $(BROWSERTESTS) + +lib-cov: + jscoverage lib lib-cov + +superagent.js: lib/node/*.js lib/node/parsers/*.js + @./node_modules/.bin/browserify \ + --standalone superagent \ + --outfile superagent.js . + +test-server: + @node test/server + +docs: index.html test-docs + +index.html: docs/index.md + marked < $< \ + | cat docs/head.html - docs/tail.html \ + > $@ + +docclean: + rm -f index.html test.html + +test-docs: + make test REPORTER=doc \ + | cat docs/head.html - docs/tail.html \ + > test.html + +clean: + rm -fr superagent.js components + +.PHONY: test-cov test docs test-docs clean test-browser-local diff --git a/node_modules/supertest/node_modules/superagent/Readme.md b/node_modules/supertest/node_modules/superagent/Readme.md new file mode 100644 index 0000000..eed472d --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/Readme.md @@ -0,0 +1,116 @@ +# SuperAgent [![Build Status](https://travis-ci.org/visionmedia/superagent.svg?branch=master)](https://travis-ci.org/visionmedia/superagent) + +[![Sauce Test Status](https://saucelabs.com/browser-matrix/shtylman-superagent.svg)](https://saucelabs.com/u/shtylman-superagent) + +SuperAgent is a small progressive __client-side__ HTTP request library, and __Node.js__ module with the same API, sporting many high-level HTTP client features. View the [docs](http://visionmedia.github.io/superagent/). + +![super agent](http://f.cl.ly/items/3d282n3A0h0Z0K2w0q2a/Screenshot.png) + +## Installation + +node: + +``` +$ npm install superagent +``` + +component: + +``` +$ component install visionmedia/superagent +``` + +Works with [browserify](https://github.com/substack/node-browserify) and should work with [webpack](https://github.com/visionmedia/superagent/wiki/Superagent-for-Webpack) + +```js +request + .post('/api/pet') + .send({ name: 'Manny', species: 'cat' }) + .set('X-API-Key', 'foobar') + .set('Accept', 'application/json') + .end(function(err, res){ + // Calling the end function will send the request + }); +``` + +## Supported browsers + +Tested browsers: + +- Latest Android +- Latest Firefox +- Latest Chrome +- IE9 through latest +- Latest iPhone +- Latest Safari + +Even though IE9 is supported, a polyfill `window.btoa` is needed to use basic auth. + +# Plugins + +Superagent is easily extended via plugins. + +```js +var nocache = require('superagent-no-cache'); +var request = require('superagent'); +var prefix = require('superagent-prefix')('/static'); + +request +.get('/some-url') +.use(prefix) // Prefixes *only* this request +.use(nocache) // Prevents caching of *only* this request +.end(function(err, res){ + // Do something +}); +``` + +Existing plugins: + * [superagent-no-cache](https://github.com/johntron/superagent-no-cache) - prevents caching by including Cache-Control header + * [superagent-prefix](https://github.com/johntron/superagent-prefix) - prefixes absolute URLs (useful in test environment) + * [superagent-suffix](https://github.com/timneutkens1/superagent-suffix) - suffix URLs with a given path + * [superagent-mock](https://github.com/M6Web/superagent-mock) - simulate HTTP calls by returning data fixtures based on the requested URL + * [superagent-mocker](https://github.com/shuvalov-anton/superagent-mocker) — simulate REST API + * [superagent-cache](https://github.com/jpodwys/superagent-cache) - superagent with built-in, flexible caching + * [superagent-jsonapify](https://github.com/alex94puchades/superagent-jsonapify) - A lightweight [json-api](http://jsonapi.org/format/) client addon for superagent + * [superagent-serializer](https://github.com/zzarcon/superagent-serializer) - Converts server payload into different cases + * [superagent-promise-plugin](https://github.com/jomaxx/superagent-promise-plugin) - Shims req.end to return a promise when executed with no callback. + * [superagent-use](https://github.com/koenpunt/superagent-use) - A client addon to apply plugins to all requests. + +Please prefix your plugin with `superagent-*` so that it can easily be found by others. + +For superagent extensions such as couchdb and oauth visit the [wiki](https://github.com/visionmedia/superagent/wiki). + +## Running node tests + +Install dependencies: + +```shell +$ npm install +``` +Run em! + +```shell +$ make test +``` + +## Running browser tests + +Install dependencies: + +```shell +$ npm install +``` + +Start the test runner: + +```shell +$ make test-browser-local +``` + +Visit `http://localhost:4000/__zuul` in your browser. + +Edit tests and refresh your browser. You do not have to restart the test runner. + +## License + +MIT diff --git a/node_modules/supertest/node_modules/superagent/bower.json b/node_modules/supertest/node_modules/superagent/bower.json new file mode 100644 index 0000000..d01423c --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/bower.json @@ -0,0 +1,4 @@ +{ + "name": "superagent", + "main": "lib/client.js" +} diff --git a/node_modules/supertest/node_modules/superagent/component.json b/node_modules/supertest/node_modules/superagent/component.json new file mode 100644 index 0000000..f192fbd --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/component.json @@ -0,0 +1,21 @@ +{ + "name": "superagent", + "repo": "visionmedia/superagent", + "version": "1.8.3", + "description": "elegant & feature rich browser / node HTTP with a fluent API", + "keywords": [ + "http", + "ajax", + "request", + "agent" + ], + "scripts": [ + "lib/client.js" + ], + "main": "lib/client.js", + "dependencies": { + "component/emitter": "*", + "component/reduce": "*" + }, + "license": "MIT" +} diff --git a/node_modules/supertest/node_modules/superagent/docs/head.html b/node_modules/supertest/node_modules/superagent/docs/head.html new file mode 100644 index 0000000..4d3bc50 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/docs/head.html @@ -0,0 +1,21 @@ + + + + SuperAgent - Ajax with less suck + + + + + + + + + +
    diff --git a/node_modules/supertest/node_modules/superagent/docs/highlight.js b/node_modules/supertest/node_modules/superagent/docs/highlight.js new file mode 100644 index 0000000..b37eefb --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/docs/highlight.js @@ -0,0 +1,17 @@ + +$(function(){ + $('code').each(function(){ + $(this).html(highlight($(this).text())); + }); +}); + +function highlight(js) { + return js + .replace(//g, '>') + .replace(/('.*?')/gm, '$1') + .replace(/(\d+\.\d+)/gm, '$1') + .replace(/(\d+)/gm, '$1') + .replace(/\bnew *(\w+)/gm, 'new $1') + .replace(/\b(function|new|throw|return|var|if|else)\b/gm, '$1') +} \ No newline at end of file diff --git a/node_modules/supertest/node_modules/superagent/docs/images/bg.png b/node_modules/supertest/node_modules/superagent/docs/images/bg.png new file mode 100644 index 0000000..ca3d267 Binary files /dev/null and b/node_modules/supertest/node_modules/superagent/docs/images/bg.png differ diff --git a/node_modules/supertest/node_modules/superagent/docs/index.md b/node_modules/supertest/node_modules/superagent/docs/index.md new file mode 100644 index 0000000..3dc9843 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/docs/index.md @@ -0,0 +1,448 @@ + +# SuperAgent + + Super Agent is light-weight progressive ajax API crafted for flexibility, readability, and a low learning curve after being frustrated with many of the existing request APIs. It also works with Node.js! + + request + .post('/api/pet') + .send({ name: 'Manny', species: 'cat' }) + .set('X-API-Key', 'foobar') + .set('Accept', 'application/json') + .end(function(err, res){ + if (err || !res.ok) { + alert('Oh no! error'); + } else { + alert('yay got ' + JSON.stringify(res.body)); + } + }); + +## Test documentation + + The following [test documentation](docs/test.html) was generated with [Mocha's](http://visionmedia.github.com/mocha) "doc" reporter, and directly reflects the test suite. This provides an additional source of documentation. + +## Request basics + + A request can be initiated by invoking the appropriate method on the `request` object, then calling `.end()` to send the request. For example a simple GET request: + + request + .get('/search') + .end(function(err, res){ + + }); + + A method string may also be passed: + + request('GET', '/search').end(callback); + + The __node__ client may also provide absolute urls: + + request + .get('http://example.com/search') + .end(function(err, res){ + + }); + + __DELETE__, __HEAD__, __POST__, __PUT__ and other __HTTP__ verbs may also be used, simply change the method name: + + request + .head('/favicon.ico') + .end(function(err, res){ + + }); + + __DELETE__ is a special-case, as it's a reserved word, so the method is named `.del()`: + + request + .del('/user/1') + .end(function(err, res){ + + }); + + The HTTP method defaults to __GET__, so if you wish, the following is valid: + + request('/search', function(err, res){ + + }); + +## Setting header fields + + Setting header fields is simple, invoke `.set()` with a field name and value: + + request + .get('/search') + .set('API-Key', 'foobar') + .set('Accept', 'application/json') + .end(callback); + + You may also pass an object to set several fields in a single call: + + request + .get('/search') + .set({ 'API-Key': 'foobar', Accept: 'application/json' }) + .end(callback); + +## GET requests + + The `.query()` method accepts objects, which when used with the __GET__ method will form a query-string. The following will produce the path `/search?query=Manny&range=1..5&order=desc`. + + request + .get('/search') + .query({ query: 'Manny' }) + .query({ range: '1..5' }) + .query({ order: 'desc' }) + .end(function(err, res){ + + }); + + Or as a single object: + + request + .get('/search') + .query({ query: 'Manny', range: '1..5', order: 'desc' }) + .end(function(err, res){ + + }); + + The `.query()` method accepts strings as well: + + request + .get('/querystring') + .query('search=Manny&range=1..5') + .end(function(err, res){ + + }); + + Or joined: + + request + .get('/querystring') + .query('search=Manny') + .query('range=1..5') + .end(function(err, res){ + + }); + +## HEAD requests + +You can also use the `.query()` method for HEAD requests. The following will produce the path `/users?email=joe@smith.com`. + + request + .head('/users') + .query({ email: 'joe@smith.com' }) + .end(function(err, res){ + + }); + +## POST / PUT requests + + A typical JSON __POST__ request might look a little like the following, where we set the Content-Type header field appropriately, and "write" some data, in this case just a JSON string. + + request.post('/user') + .set('Content-Type', 'application/json') + .send('{"name":"tj","pet":"tobi"}') + .end(callback) + + Since JSON is undoubtably the most common, it's the _default_! The following example is equivalent to the previous. + + request.post('/user') + .send({ name: 'tj', pet: 'tobi' }) + .end(callback) + + Or using multiple `.send()` calls: + + request.post('/user') + .send({ name: 'tj' }) + .send({ pet: 'tobi' }) + .end(callback) + + By default sending strings will set the Content-Type to `application/x-www-form-urlencoded`, + multiple calls will be concatenated with `&`, here resulting in `name=tj&pet=tobi`: + + request.post('/user') + .send('name=tj') + .send('pet=tobi') + .end(callback); + + SuperAgent formats are extensible, however by default "json" and "form" are supported. To send the data as `application/x-www-form-urlencoded` simply invoke `.type()` with "form", where the default is "json". This request will POST the body "name=tj&pet=tobi". + + request.post('/user') + .type('form') + .send({ name: 'tj' }) + .send({ pet: 'tobi' }) + .end(callback) + + Note: "form" is aliased as "form-data" and "urlencoded" for backwards compat. + +## Setting the Content-Type + + The obvious solution is to use the `.set()` method: + + request.post('/user') + .set('Content-Type', 'application/json') + + As a short-hand the `.type()` method is also available, accepting + the canonicalized MIME type name complete with type/subtype, or + simply the extension name such as "xml", "json", "png", etc: + + request.post('/user') + .type('application/json') + + request.post('/user') + .type('json') + + request.post('/user') + .type('png') + +## Setting Accept + +In a similar fashion to the `.type()` method it is also possible to set the Accept header via the short hand method `.accept()`. Which references `request.types` as well allowing you to specify either the full canonicalized MIME type name as type/subtype, or the extension suffix form as "xml", "json", "png", etc for convenience: + + request.get('/user') + .accept('application/json') + + request.get('/user') + .accept('json') + + request.post('/user') + .accept('png') + +## Query strings + + `res.query(obj)` is a method which may be used to build up a query-string. For example populating `?format=json&dest=/login` on a __POST__: + + request + .post('/') + .query({ format: 'json' }) + .query({ dest: '/login' }) + .send({ post: 'data', here: 'wahoo' }) + .end(callback); + +## Parsing response bodies + + Super Agent will parse known response-body data for you, currently supporting _application/x-www-form-urlencoded_, _application/json_, and _multipart/form-data_. + +### JSON / Urlencoded + + The property `res.body` is the parsed object, for example if a request responded with the JSON string '{"user":{"name":"tobi"}}', `res.body.user.name` would be "tobi". Likewise the x-www-form-urlencoded value of "user[name]=tobi" would yield the same result. + +### Multipart + + The Node client supports _multipart/form-data_ via the [Formidable](https://github.com/felixge/node-formidable) module. When parsing multipart responses, the object `res.files` is also available to you. Suppose for example a request responds with the following multipart body: + + --whoop + Content-Disposition: attachment; name="image"; filename="tobi.png" + Content-Type: image/png + + ... data here ... + --whoop + Content-Disposition: form-data; name="name" + Content-Type: text/plain + + Tobi + --whoop-- + + You would have the values `res.body.name` provided as "Tobi", and `res.files.image` as a `File` object containing the path on disk, filename, and other properties. + +## Response properties + + Many helpful flags and properties are set on the `Response` object, ranging from the response text, parsed response body, header fields, status flags and more. + +### Response text + + The `res.text` property contains the unparsed response body string. This + property is always present for the client API, and only when the mime type + matches "text/*", "*/json", or "x-www-form-urlencoding" by default for node. The + reasoning is to conserve memory, as buffering text of large bodies such as multipart files or images is extremely inefficient. + + To force buffering see the "Buffering responses" section. + +### Response body + + Much like SuperAgent can auto-serialize request data, it can also automatically parse it. When a parser is defined for the Content-Type, it is parsed, which by default includes "application/json" and "application/x-www-form-urlencoded". The parsed object is then available via `res.body`. + +### Response header fields + + The `res.header` contains an object of parsed header fields, lowercasing field names much like node does. For example `res.header['content-length']`. + +### Response Content-Type + + The Content-Type response header is special-cased, providing `res.type`, which is void of the charset (if any). For example the Content-Type of "text/html; charset=utf8" will provide "text/html" as `res.type`, and the `res.charset` property would then contain "utf8". + +### Response status + + The response status flags help determine if the request was a success, among other useful information, making SuperAgent ideal for interacting with RESTful web services. These flags are currently defined as: + + var type = status / 100 | 0; + + // status / class + res.status = status; + res.statusType = type; + + // basics + res.info = 1 == type; + res.ok = 2 == type; + res.clientError = 4 == type; + res.serverError = 5 == type; + res.error = 4 == type || 5 == type; + + // sugar + res.accepted = 202 == status; + res.noContent = 204 == status || 1223 == status; + res.badRequest = 400 == status; + res.unauthorized = 401 == status; + res.notAcceptable = 406 == status; + res.notFound = 404 == status; + res.forbidden = 403 == status; + +## Aborting requests + + To abort requests simply invoke the `req.abort()` method. + +## Request timeouts + + A timeout can be applied by invoking `req.timeout(ms)`, after which an error + will be triggered. To differentiate between other errors the `err.timeout` property + is set to the `ms` value. __NOTE__ that this is a timeout applied to the request + and all subsequent redirects, not per request. + +## Basic authentication + + Basic auth is currently provided by the _node_ client in two forms, first via the URL as "user:pass": + + request.get('http://tobi:learnboost@local').end(callback); + + As well as via the `.auth()` method: + + request + .get('http://local') + .auth('tobi', 'learnboost') + .end(callback); + +## Following redirects + + By default up to 5 redirects will be followed, however you may specify this with the `res.redirects(n)` method: + + request + .get('/some.png') + .redirects(2) + .end(callback); + +## Piping data + + The Node client allows you to pipe data to and from the request. For example piping a file's contents as the request: + + var request = require('superagent') + , fs = require('fs'); + + var stream = fs.createReadStream('path/to/my.json'); + var req = request.post('/somewhere'); + req.type('json'); + stream.pipe(req); + + Or piping the response to a file: + + var request = require('superagent') + , fs = require('fs'); + + var stream = fs.createWriteStream('path/to/my.json'); + var req = request.get('/some.json'); + req.pipe(stream); + +## Multipart requests + + Super Agent is also great for _building_ multipart requests for which it provides methods `.attach()` and `.field()`. + +### Attaching files + + As mentioned a higher-level API is also provided, in the form of `.attach(name, [path], [filename])` and `.field(name, value)`. Attaching several files is simple, you can also provide a custom filename for the attachment, otherwise the basename of the attached file is used. + + request + .post('/upload') + .attach('avatar', 'path/to/tobi.png', 'user.png') + .attach('image', 'path/to/loki.png') + .attach('file', 'path/to/jane.png') + .end(callback); + +### Field values + + Much like form fields in HTML, you can set field values with the `.field(name, value)` method. Suppose you want to upload a few images with your name and email, your request might look something like this: + + request + .post('/upload') + .field('user[name]', 'Tobi') + .field('user[email]', 'tobi@learnboost.com') + .attach('image', 'path/to/tobi.png') + .end(callback); + +## Compression + + The node client supports compressed responses, best of all, you don't have to do anything! It just works. + +## Buffering responses + + To force buffering of response bodies as `res.text` you may invoke `req.buffer()`. To undo the default of buffering for text responses such + as "text/plain", "text/html" etc you may invoke `req.buffer(false)`. + + When buffered the `res.buffered` flag is provided, you may use this to + handle both buffered and unbuffered responses in the same callback. + +## CORS + + The `.withCredentials()` method enables the ability to send cookies + from the origin, however only when "Access-Control-Allow-Origin" is + _not_ a wildcard ("*"), and "Access-Control-Allow-Credentials" is "true". + + request + .get('http://localhost:4001/') + .withCredentials() + .end(function(err, res){ + assert(200 == res.status); + assert('tobi' == res.text); + next(); + }) + +## Error handling + +Your callback function will always be passed two arguments: error and response. If no error occurred, the first argument will be null: + + request + .post('/upload') + .attach('image', 'path/to/tobi.png') + .end(function(err, res){ + + }); + + An "error" event is also emitted, with you can listen for: + + request + .post('/upload') + .attach('image', 'path/to/tobi.png') + .on('error', handle) + .end(function(err, res){ + + }); + + Note that a 4xx or 5xx response with super agent **are** considered an error by default. For example if you get a 500 or 403 response, this status information will be available via `err.status`. Errors from such responses also contain an `err.response` field with all of the properties mentioned in "Response properties". The library behaves in this way to handle the common case of wanting success responses and treating HTTP error status codes as errors while still allowing for custom logic around specific error conditions. + + Network failures, timeouts, and other errors that produce no response will contain no `err.status` or `err.response` fields. + + If you wish to handle 404 or other HTTP error responses, you can query the `err.status` property. + When an HTTP error occurs (4xx or 5xx response) the `res.error` property is an `Error` object, + this allows you to perform checks such as: + + if (err && err.status === 404) { + alert('oh no ' + res.body.message); + } + else if (err) { + // all other error types we handle generically + } + +## Generator support + +Superagent now supports easier control flow using generators. By using a generator control flow +like [co](https://github.com/tj/co) or a web framework like [koa](https://github.com/koajs/koa), +you can `yield` on any superagent method: + + var res = yield request + .get('http://local') + .auth('tobi', 'learnboost') diff --git a/node_modules/supertest/node_modules/superagent/docs/jquery-ui.min.js b/node_modules/supertest/node_modules/superagent/docs/jquery-ui.min.js new file mode 100644 index 0000000..932f867 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/docs/jquery-ui.min.js @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.11.4 - 2015-11-20 +* http://jqueryui.com +* Includes: widget.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +(function(e){"function"==typeof define&&define.amd?define(["jquery"],e):e(jQuery)})(function(e){var t=0,i=Array.prototype.slice;e.cleanData=function(t){return function(i){var s,n,a;for(a=0;null!=(n=i[a]);a++)try{s=e._data(n,"events"),s&&s.remove&&e(n).triggerHandler("remove")}catch(o){}t(i)}}(e.cleanData),e.widget=function(t,i,s){var n,a,o,r,h={},l=t.split(".")[0];return t=t.split(".")[1],n=l+"-"+t,s||(s=i,i=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[l]=e[l]||{},a=e[l][t],o=e[l][t]=function(e,t){return this._createWidget?(arguments.length&&this._createWidget(e,t),void 0):new o(e,t)},e.extend(o,a,{version:s.version,_proto:e.extend({},s),_childConstructors:[]}),r=new i,r.options=e.widget.extend({},r.options),e.each(s,function(t,s){return e.isFunction(s)?(h[t]=function(){var e=function(){return i.prototype[t].apply(this,arguments)},n=function(e){return i.prototype[t].apply(this,e)};return function(){var t,i=this._super,a=this._superApply;return this._super=e,this._superApply=n,t=s.apply(this,arguments),this._super=i,this._superApply=a,t}}(),void 0):(h[t]=s,void 0)}),o.prototype=e.widget.extend(r,{widgetEventPrefix:a?r.widgetEventPrefix||t:t},h,{constructor:o,namespace:l,widgetName:t,widgetFullName:n}),a?(e.each(a._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete a._childConstructors):i._childConstructors.push(o),e.widget.bridge(t,o),o},e.widget.extend=function(t){for(var s,n,a=i.call(arguments,1),o=0,r=a.length;r>o;o++)for(s in a[o])n=a[o][s],a[o].hasOwnProperty(s)&&void 0!==n&&(t[s]=e.isPlainObject(n)?e.isPlainObject(t[s])?e.widget.extend({},t[s],n):e.widget.extend({},n):n);return t},e.widget.bridge=function(t,s){var n=s.prototype.widgetFullName||t;e.fn[t]=function(a){var o="string"==typeof a,r=i.call(arguments,1),h=this;return o?this.each(function(){var i,s=e.data(this,n);return"instance"===a?(h=s,!1):s?e.isFunction(s[a])&&"_"!==a.charAt(0)?(i=s[a].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):e.error("no such method '"+a+"' for "+t+" widget instance"):e.error("cannot call methods on "+t+" prior to initialization; "+"attempted to call method '"+a+"'")}):(r.length&&(a=e.widget.extend.apply(null,[a].concat(r))),this.each(function(){var t=e.data(this,n);t?(t.option(a||{}),t._init&&t._init()):e.data(this,n,new s(a,this))})),h}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{disabled:!1,create:null},_createWidget:function(i,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=t++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this.options=e.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(t,i){var s,n,a,o=t;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof t)if(o={},s=t.split("."),t=s.shift(),s.length){for(n=o[t]=e.widget.extend({},this.options[t]),a=0;s.length-1>a;a++)n[s[a]]=n[s[a]]||{},n=n[s[a]];if(t=s.pop(),1===arguments.length)return void 0===n[t]?null:n[t];n[t]=i}else{if(1===arguments.length)return void 0===this.options[t]?null:this.options[t];o[t]=i}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled",!!t),t&&(this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus"))),this},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_on:function(t,i,s){var n,a=this;"boolean"!=typeof t&&(s=i,i=t,t=!1),s?(i=n=e(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),e.each(s,function(s,o){function r(){return t||a.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?a[o]:o).apply(a,arguments):void 0}"string"!=typeof o&&(r.guid=o.guid=o.guid||r.guid||e.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+a.eventNamespace,u=h[2];u?n.delegate(u,l,r):i.bind(l,r)})},_off:function(t,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(i).undelegate(i),this.bindings=e(this.bindings.not(t).get()),this.focusable=e(this.focusable.not(t).get()),this.hoverable=e(this.hoverable.not(t).get())},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,o=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(o)&&o.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var o,r=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),o=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),o&&e.effects&&e.effects.effect[r]?s[t](n):r!==t&&s[r]?s[r](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}}),e.widget}); \ No newline at end of file diff --git a/node_modules/supertest/node_modules/superagent/docs/jquery.js b/node_modules/supertest/node_modules/superagent/docs/jquery.js new file mode 100644 index 0000000..d2424e6 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/docs/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7 jquery.com | jquery.org/license */ +(function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"":"")+""),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
    a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="
    ",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
    t
    ",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p="
    "+""+"
    ";m=c.getElementsByTagName("body")[0];!m||(a=c.createElement("div"),a.style.cssText=l+"width:0;height:0;position:static;top:0;margin-top:"+i+"px",m.insertBefore(a,m.firstChild),o=c.createElement("div"),o.style.cssText=j+l,o.innerHTML=p,a.appendChild(o),b=o.firstChild,d=b.firstChild,g=b.nextSibling.firstChild.firstChild,h={doesNotAddBorder:d.offsetTop!==5,doesAddBorderForTableAndCells:g.offsetTop===5},d.style.position="fixed",d.style.top="20px",h.fixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",b.style.overflow="hidden",b.style.position="relative",h.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,h.doesNotIncludeMarginInBodyOffset=m.offsetTop!==i,m.removeChild(a),o=a=null,f.extend(k,h))}),o.innerHTML="",n.removeChild(o),o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[f.expando]:a[f.expando]&&f.expando,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[f.expando]=n=++f.uuid:n=f.expando),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[f.expando]:f.expando;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)?b=b:b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" "));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];if(!arguments.length){if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}return b}e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!a||j===3||j===8||j===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g},removeAttr:function(a,b){var c,d,e,g,h=0;if(a.nodeType===1){d=(b||"").split(p),g=d.length;for(;h=0}})});var z=/\.(.*)$/,A=/^(?:textarea|input|select)$/i,B=/\./g,C=/ /g,D=/[^\w\s.|`]/g,E=/^([^\.]*)?(?:\.(.+))?$/,F=/\bhover(\.\S+)?/,G=/^key/,H=/^(?:mouse|contextmenu)|click/,I=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,J=function(a){var b=I.exec(a);b&& +(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},K=function(a,b){return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||a.id===b[2])&&(!b[3]||b[3].test(a.className))},L=function(a){return f.event.special.hover?a:a.replace(F,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=L(c).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"",(g||!e)&&c.preventDefault();if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,n=null;for(m=e.parentNode;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l=0:t===b&&(t=o[s]=r.quick?K(m,r.quick):f(m).is(s)),t&&q.push(r);q.length&&j.push({elem:m,matches:q})}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),G.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),H.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y="abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",Z=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,_=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,ba=/<([\w:]+)/,bb=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bk=X(c);bj.optgroup=bj.option,bj.tbody=bj.tfoot=bj.colgroup=bj.caption=bj.thead,bj.th=bj.td,f.support.htmlSerialize||(bj._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after" +,arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Z,""):null;if(typeof a=="string"&&!bd.test(a)&&(f.support.leadingWhitespace||!$.test(a))&&!bj[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(_,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bn(a,d),e=bo(a),g=bo(d);for(h=0;e[h];++h)g[h]&&bn(e[h],g[h])}if(b){bm(a,d);if(c){e=bo(a),g=bo(d);for(h=0;e[h];++h)bm(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bc.test(k))k=b.createTextNode(k);else{k=k.replace(_,"<$1>");var l=(ba.exec(k)||["",""])[1].toLowerCase(),m=bj[l]||bj._default,n=m[0],o=b.createElement("div");b===c?bk.appendChild(o):X(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=bb.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&$.test(k)&&o.insertBefore(b.createTextNode($.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bt.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bs,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bs.test(g)?g.replace(bs,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bB(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bC=function(a,c){var d,e,g;c=c.replace(bu,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bD=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bv.test(f)&&bw.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bB=bC||bD,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bF=/%20/g,bG=/\[\]$/,bH=/\r?\n/g,bI=/#.*$/,bJ=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bK=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bL=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bM=/^(?:GET|HEAD)$/,bN=/^\/\//,bO=/\?/,bP=/)<[^<]*)*<\/script>/gi,bQ=/^(?:select|textarea)/i,bR=/\s+/,bS=/([?&])_=[^&]*/,bT=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bU=f.fn.load,bV={},bW={},bX,bY,bZ=["*/"]+["*"];try{bX=e.href}catch(b$){bX=c.createElement("a"),bX.href="",bX=bX.href}bY=bT.exec(bX.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bU)return bU.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bP,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bQ.test(this.nodeName)||bK.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bH,"\r\n")}}):{name:b.name,value:c.replace(bH,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?cb(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),cb(a,b);return a},ajaxSettings:{url:bX,isLocal:bL.test(bY[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bZ},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:b_(bV),ajaxTransport:b_(bW),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cd(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=ce(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bJ.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bI,"").replace(bN,bY[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bR),d.crossDomain==null&&(r=bT.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bY[1]&&r[2]==bY[2]&&(r[3]||(r[1]==="http:"?80:443))==(bY[3]||(bY[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),ca(bV,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bM.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bO.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bS,"$1_="+x);d.url=y+(y===d.url?(bO.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bZ+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=ca(bW,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)cc(g,a[g],c,e);return d.join("&").replace(bF,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cf=f.now(),cg=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cf++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cg.test(b.url)||e&&cg.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cg,l),b.url===j&&(e&&(k=k.replace(cg,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ch=a.ActiveXObject?function(){for(var a in cj)cj[a](0,1)}:!1,ci=0,cj;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ck()||cl()}:ck,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ch&&delete cj[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++ci,ch&&(cj||(cj={},f(a).unload(ch)),cj[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cm={},cn,co,cp=/^(?:toggle|show|hide)$/,cq=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cr,cs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],ct;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cw("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cz.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cz.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cA(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cA(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/node_modules/supertest/node_modules/superagent/docs/jquery.tocify.min.js b/node_modules/supertest/node_modules/superagent/docs/jquery.tocify.min.js new file mode 100755 index 0000000..0fc0442 --- /dev/null +++ b/node_modules/supertest/node_modules/superagent/docs/jquery.tocify.min.js @@ -0,0 +1,4 @@ +/*! jquery.tocify - v1.9.0 - 2013-10-01 +* http://gregfranko.com/jquery.tocify.js/ +* Copyright (c) 2013 Greg Franko; Licensed MIT*/ +(function(e){"use strict";e(window.jQuery,window,document)})(function(e,t,s){"use strict";var i="tocify",o="tocify-focus",n="tocify-hover",a="tocify-hide",l="tocify-header",h="."+l,r="tocify-subheader",d="."+r,c="tocify-item",f="."+c,u="tocify-extend-page",p="."+u;e.widget("toc.tocify",{version:"1.9.0",options:{context:"body",ignoreSelector:null,selectors:"h1, h2, h3",showAndHide:!0,showEffect:"slideDown",showEffectSpeed:"medium",hideEffect:"slideUp",hideEffectSpeed:"medium",smoothScroll:!0,smoothScrollSpeed:"medium",scrollTo:0,showAndHideOnScroll:!0,highlightOnScroll:!0,highlightOffset:40,theme:"bootstrap",extendPage:!0,extendPageOffset:100,history:!0,scrollHistory:!1,hashGenerator:"compact",highlightDefault:!0},_create:function(){var s=this;s.extendPageScroll=!0,s.items=[],s._generateToc(),s._addCSSClasses(),s.webkit=function(){for(var e in t)if(e&&-1!==e.toLowerCase().indexOf("webkit"))return!0;return!1}(),s._setEventHandlers(),e(t).load(function(){s._setActiveElement(!0),e("html, body").promise().done(function(){setTimeout(function(){s.extendPageScroll=!1},0)})})},_generateToc:function(){var t,s,o=this,n=o.options.ignoreSelector;return t=-1!==this.options.selectors.indexOf(",")?e(this.options.context).find(this.options.selectors.replace(/ /g,"").substr(0,this.options.selectors.indexOf(","))):e(this.options.context).find(this.options.selectors.replace(/ /g,"")),t.length?(o.element.addClass(i),t.each(function(t){e(this).is(n)||(s=e("